感谢尚硅谷免费视频与资料 http://www.atguigu.com/

一、Dubbo RPC原理


一次完整的RPC调用流程(同步调用,异步另说)如下:
1)服务消费方(client)调用以本地调用方式调用服务;
2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
3)client stub找到服务地址,并将消息发送到服务端;
4)server stub收到消息后进行解码;
5)server stub根据解码结果调用本地的服务;
6)本地服务执行并将结果返回给server stub;
7)server stub将返回结果打包成消息并发送至消费方;
8)client stub接收到消息,并进行解码;
9)服务消费方得到最终结果。
RPC框架(Dubbo等)的目标就是要2~8这些步骤都封装起来,这些细节对用户来说是透明的,不可见的。

二、Netty 通信原理

Netty是一个异步事件驱动的网络应用程序框架(NIO), 用于快速开发可维护的高性能协议服务器和客户端。它极大地简化并简化了TCP和UDP套接字服务器等网络编程。
BIO:(Blocking IO):阻塞IO

NIO (Non-Blocking IO):非阻塞IO

Selector 一般称 为选择器 ,也可以翻译为 多路复用器,
Connect(连接就绪)、Accept(接受就绪)、Read(读就绪)、Write(写就绪)

Netty基本原理:
Netty是基于NIO的多路复用

Dubbo原理 架构设计

http://dubbo.apache.org/zh-cn/docs/dev/design.html

  • Business 这是我们的业务 自己写代码

    RPC层完成远程调用:

  • config 配置层:对外配置接口,以 ServiceConfig, ReferenceConfig 为中心,可以直接初始化配置类,也可以通过 spring 解析配置生成配置类 这个就是收集配置的数据!!

  • proxy 服务代理层:服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton, 以 ServiceProxy 为中心,扩展接口为 ProxyFactory

  • registry 注册中心层:封装服务地址的注册与发现,以服务 URL 为中心,扩展接口为 RegistryFactory, Registry, RegistryService 服务的发现和服务的注册

  • cluster 路由层:封装多个提供者的路由及负载均衡,并桥接注册中心,以 Invoker 为中心,扩展接口为 Cluster, Directory, Router, LoadBalance

  • monitor 监控层:RPC 调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactory, Monitor, MonitorService

  • protocol 远程调用层:封装 RPC 调用,以 Invocation, Result 为中心,扩展接口为 Protocol, Invoker, Exporter

    Remoting解决远程通讯 :

  • exchange 信息交换层:封装请求响应模式,同步转异步,以 Request, Response 为中心,扩展接口为 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer

  • transport 网络传输层:抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 Channel, Transporter, Client, Server, Codec

  • serialize 数据序列化层:可复用的一些工具,扩展接口为 Serialization, ObjectInput, ObjectOutput, ThreadPool

Dubbo标签解析

Spring解析标签都有一个类叫BeanDefinitionParser
而解析Dubbo的类是DubboBeanDefinitionParser
解析配置类的目的 就是把配置文件的信息封装成一个一个的xxxxConfig
当然 service 和 reference 是封装成xxBean

public class DubboNamespaceHandler extends NamespaceHandlerSupport {static {Version.checkDuplicate(DubboNamespaceHandler.class);}@Overridepublic void init() {registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));registerBeanDefinitionParser("config-center", new DubboBeanDefinitionParser(ConfigCenterBean.class, true));registerBeanDefinitionParser("metadata-report", new DubboBeanDefinitionParser(MetadataReportConfig.class, true));registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));registerBeanDefinitionParser("annotation", new AnnotationBeanDefinitionParser());}}
@SuppressWarnings("unchecked")private static BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) {RootBeanDefinition beanDefinition = new RootBeanDefinition();beanDefinition.setBeanClass(beanClass);beanDefinition.setLazyInit(false);String id = element.getAttribute("id");if ((id == null || id.length() == 0) && required) {String generatedBeanName = element.getAttribute("name");if (generatedBeanName == null || generatedBeanName.length() == 0) {if (ProtocolConfig.class.equals(beanClass)) {generatedBeanName = "dubbo";} else {generatedBeanName = element.getAttribute("interface");}}if (generatedBeanName == null || generatedBeanName.length() == 0) {generatedBeanName = beanClass.getName();}id = generatedBeanName;int counter = 2;while (parserContext.getRegistry().containsBeanDefinition(id)) {id = generatedBeanName + (counter++);}}if (id != null && id.length() > 0) {if (parserContext.getRegistry().containsBeanDefinition(id)) {throw new IllegalStateException("Duplicate spring bean id " + id);}parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);beanDefinition.getPropertyValues().addPropertyValue("id", id);}if (ProtocolConfig.class.equals(beanClass)) {for (String name : parserContext.getRegistry().getBeanDefinitionNames()) {BeanDefinition definition = parserContext.getRegistry().getBeanDefinition(name);PropertyValue property = definition.getPropertyValues().getPropertyValue("protocol");if (property != null) {Object value = property.getValue();if (value instanceof ProtocolConfig && id.equals(((ProtocolConfig) value).getName())) {definition.getPropertyValues().addPropertyValue("protocol", new RuntimeBeanReference(id));}}}} else if (ServiceBean.class.equals(beanClass)) {String className = element.getAttribute("class");if (className != null && className.length() > 0) {RootBeanDefinition classDefinition = new RootBeanDefinition();classDefinition.setBeanClass(ReflectUtils.forName(className));classDefinition.setLazyInit(false);parseProperties(element.getChildNodes(), classDefinition);beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl"));}} else if (ProviderConfig.class.equals(beanClass)) {parseNested(element, parserContext, ServiceBean.class, true, "service", "provider", id, beanDefinition);} else if (ConsumerConfig.class.equals(beanClass)) {parseNested(element, parserContext, ReferenceBean.class, false, "reference", "consumer", id, beanDefinition);}Set<String> props = new HashSet<String>();ManagedMap parameters = null;for (Method setter : beanClass.getMethods()) {String name = setter.getName();if (name.length() > 3 && name.startsWith("set")&& Modifier.isPublic(setter.getModifiers())&& setter.getParameterTypes().length == 1) {Class<?> type = setter.getParameterTypes()[0];String beanProperty = name.substring(3, 4).toLowerCase() + name.substring(4);String property = StringUtils.camelToSplitName(beanProperty, "-");props.add(property);Method getter = null;try {getter = beanClass.getMethod("get" + name.substring(3), new Class<?>[0]);} catch (NoSuchMethodException e) {try {getter = beanClass.getMethod("is" + name.substring(3), new Class<?>[0]);} catch (NoSuchMethodException e2) {}}if (getter == null|| !Modifier.isPublic(getter.getModifiers())|| !type.equals(getter.getReturnType())) {continue;}if ("parameters".equals(property)) {parameters = parseParameters(element.getChildNodes(), beanDefinition);} else if ("methods".equals(property)) {parseMethods(id, element.getChildNodes(), beanDefinition, parserContext);} else if ("arguments".equals(property)) {parseArguments(id, element.getChildNodes(), beanDefinition, parserContext);} else {String value = element.getAttribute(property);if (value != null) {value = value.trim();if (value.length() > 0) {if ("registry".equals(property) && RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(value)) {RegistryConfig registryConfig = new RegistryConfig();registryConfig.setAddress(RegistryConfig.NO_AVAILABLE);beanDefinition.getPropertyValues().addPropertyValue(beanProperty, registryConfig);} else if ("provider".equals(property) || "registry".equals(property) || ("protocol".equals(property) && ServiceBean.class.equals(beanClass))) {/*** For 'provider' 'protocol' 'registry', keep literal value (should be id/name) and set the value to 'registryIds' 'providerIds' protocolIds'* The following process should make sure each id refers to the corresponding instance, here's how to find the instance for different use cases:* 1. Spring, check existing bean by id, see{@link ServiceBean#afterPropertiesSet()}; then try to use id to find configs defined in remote Config Center* 2. API, directly use id to find configs defined in remote Config Center; if all config instances are defined locally, please use {@link org.apache.dubbo.config.ServiceConfig#setRegistries(List)}*/beanDefinition.getPropertyValues().addPropertyValue(beanProperty + "Ids", value);} else {Object reference;if (isPrimitive(type)) {if ("async".equals(property) && "false".equals(value)|| "timeout".equals(property) && "0".equals(value)|| "delay".equals(property) && "0".equals(value)|| "version".equals(property) && "0.0.0".equals(value)|| "stat".equals(property) && "-1".equals(value)|| "reliable".equals(property) && "false".equals(value)) {// backward compatibility for the default value in old version's xsdvalue = null;}reference = value;} else if ("onreturn".equals(property)) {int index = value.lastIndexOf(".");String returnRef = value.substring(0, index);String returnMethod = value.substring(index + 1);reference = new RuntimeBeanReference(returnRef);beanDefinition.getPropertyValues().addPropertyValue("onreturnMethod", returnMethod);} else if ("onthrow".equals(property)) {int index = value.lastIndexOf(".");String throwRef = value.substring(0, index);String throwMethod = value.substring(index + 1);reference = new RuntimeBeanReference(throwRef);beanDefinition.getPropertyValues().addPropertyValue("onthrowMethod", throwMethod);} else if ("oninvoke".equals(property)) {int index = value.lastIndexOf(".");String invokeRef = value.substring(0, index);String invokeRefMethod = value.substring(index + 1);reference = new RuntimeBeanReference(invokeRef);beanDefinition.getPropertyValues().addPropertyValue("oninvokeMethod", invokeRefMethod);} else {if ("ref".equals(property) && parserContext.getRegistry().containsBeanDefinition(value)) {BeanDefinition refBean = parserContext.getRegistry().getBeanDefinition(value);if (!refBean.isSingleton()) {throw new IllegalStateException("The exported service ref " + value + " must be singleton! Please set the " + value + " bean scope to singleton, eg: <bean id=\"" + value + "\" scope=\"singleton\" ...>");}}reference = new RuntimeBeanReference(value);}beanDefinition.getPropertyValues().addPropertyValue(beanProperty, reference);}}}}}}NamedNodeMap attributes = element.getAttributes();int len = attributes.getLength();for (int i = 0; i < len; i++) {Node node = attributes.item(i);String name = node.getLocalName();if (!props.contains(name)) {if (parameters == null) {parameters = new ManagedMap();}String value = node.getNodeValue();parameters.put(name, new TypedStringValue(value, String.class));}}if (parameters != null) {beanDefinition.getPropertyValues().addPropertyValue("parameters", parameters);}return beanDefinition;}

Dubbo 服务暴露流程 和服务引用流程

http://dubbo.apache.org/zh-cn/docs/dev/design.html
我看了人家的视频 服务暴露的流程 我懂了的就是2点
第一点: dubbo 拿上一些东西 然后去开启netty 服务
第二点:register 把地址和执行器存储起来<url,<Set<执行器>>>

第三点:refrence 去服务中心订阅服务
第四点:拿着服务中心的订阅地址 去获取netty客户端 获取消费者的invoker(执行器 代理对象 )
第五点:register 把消费者存储<url,set<执行器>>

第五点:代理对象执行方法 ,根据负载均衡策略找见合适的invoker 然后各种filter
最后DubboInvoker 拿到客户端(refrence 的时候拿过 )远程调用 底层就是netty mina调用了
返回结果

暴露服务:

引用服务:

调用链

说实话 很难 看了也只是简单了解

Dubbo-06 20190320相关推荐

  1. 100道 Dubbo面试题及答案(2021最新)

    Redis面试题及答案[2021最新版]Dubbo面试题大全(2021版),发现网上很多Dubbo面试题都没有答案,所以花了很长时间搜集,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小 ...

  2. Dubbo常见面试题及答案汇总1000道(春招+秋招+社招)

    Dubbo面试题以及答案整理[最新版]Dubbo高级面试题大全(2021版),发现网上很多Dubbo面试题都没有答案,所以花了很长时间搜集,本套Dubbo面试题大全,汇总了大量经典的Dubbo程序员面 ...

  3. Dubbo 高危反序列化漏洞,存在远程代码执行风险,建议及时升级到2.7.7或更高版本!...

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 以下内容转载自安全客,原文链接:https://www. ...

  4. Dubbo入门实例--转载

    原文地址:http://blog.csdn.net/ruishenh/article/details/23180707?utm_source=tuicool 1.   概述 Dubbo是一个分布式服务 ...

  5. 第一个 Dubbo 应用

    Java RMI 简介 Java RMI (Remote Method Invocation)- 远程方法调用,能够让客户端像使用本地调用一样调用服务端 Java 虚拟机中的对象方法.RMI 是面向对 ...

  6. dubbo-go 白话文 | 从零搭建 dubbogo 和 dubbo 的简单用例

    作者 | 铁城 dubbo-go 社区 committer 来源|阿里巴巴云原生公众号 本文将手把手教你使用 dubbogo 调用 dubbogo 或 dubbo 提供的服务提供方. 前言 本文基于 ...

  7. Dubbo——Dubbo协议整合Jackson序列化解决方案

    环境配置 spring boot 2.6.3 spring cloud 2021.0.1 spring cloud alibaba 2021.0.1.0 nacos server 2.0.4 dubb ...

  8. SpringCloud与dubbo的区别

    我们来看一下SpringCloud和Dubbo的区别,我们准备了一个表格,会从这五个维度,出身背景,活跃度,文档质量,性能,功能,从5个维度来做SpringCloud和Dubbo的对比 Dubbo它是 ...

  9. Apache Dubbo 被曝出“高危”远程代码执行漏洞

    击上方"朱小厮的博客",选择"设为星标" 后台回复"加群",加入组织 来源:22j.co/brUT 0x01 漏洞背景 2020年06月23 ...

  10. dubbo优势_Dubbo与SpringCloud核心组件Ribbon、Hystrix、Feign的优劣势比较

    在微服务架构中,分布式通信.分布式事务.分布式锁等问题是亟待解决的几个重要问题. Spring Cloud是一套完整的微服务解决方案,基于 Spring Boot 框架.确切的说,Spring Clo ...

最新文章

  1. 吊打一切:YOLOv4的tricks汇总
  2. python循环队列_关于循环队列的一些讲解
  3. 高性能缓存服务器 Nuster
  4. python 类-Python类(class)
  5. 推荐系统遇到曝光偏差怎么办?用对比学习!
  6. 近期 AI 领域招聘、招生信息汇总
  7. 移动电话之父第一个电话打给对手,起底现代移动通信崛起之路!
  8. cookie、session、sessionid 与jsessionid之间的关系
  9. 51单片机c语言呼吸灯程序,给你的51单片机作品加个呼吸灯(程序)
  10. 小程序模仿通讯录制作
  11. 如何搜索视频和字幕?
  12. 鸿翼上线DMSTMS管理系统,助力智飞龙科马打造数字化质量安全生命线
  13. SPSS 随机区组秩和检验
  14. 基于MATLAB的AM调制解调
  15. bp神经网络预测python人口预测_BP神经网络人口预测程序(matlab实现)
  16. 【Linux】计算机组成与进程
  17. 佟年计算机大赛,佟年的人设是什么?
  18. 用计算机知道函数值求度数,怎么计算出余弦的度数
  19. java免费视频通话,GitHub标星3.2K
  20. 如何基于WebRTC搭建一个简单的视频会议

热门文章

  1. 快速去除电脑弹窗广告
  2. 勒索病毒SARA,请勿用于非法用途。
  3. module.exports 和 exports的区别
  4. filter- 配置多过滤url
  5. 实用解析dmp文件内容
  6. 数字藏品指南系列第五篇:验证智能合约
  7. C# WINFORM 主窗口把数据传给子窗口,编辑后再返回主窗口
  8. 全志V3s学习记录(13)OV2640的使用
  9. AForge学习笔记(2):AForge.Controls
  10. Android 7.0模拟来电