一、导论

dubbo作为阿里开发优秀的rpc服务框架,现已广泛用于各大rpc项目之间的远程通信,虽然阿里现在已经没有维护dubbo的开发,但是其结构设计也是值得学习。

二、结构简介

这部分只是简单介绍dubbo的结构图解,可能会有些复杂,但确实是dubbo设计的精髓所在。

1、各层介绍

  1. config,配置层,对外配置接口,以ServiceConfig, ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类,dubbo的相关配置都是该对象在维护。
  2. proxy,服务代理层,服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory。
  3. registry,注册中心层,封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory, Registry, RegistryService。
  4. cluster,路由层,封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster, Directory, Router, LoadBalance。
  5. monitor,监控层,RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory, Monitor, MonitorService。
  6. protocol,远程调用层,封将RPC调用,以Invocation, Result为中心,扩展接口为Protocol, Invoker, Exporter。
  7. exchange,信息交换层,封装请求响应模式,同步转异步,以Request, Response为中心,扩展接口为Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer。
  8. transport,网络传输层,抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel, Transporter, Client, Server, Codec。
  9. serialize,数据序列化层,可复用的一些工具,扩展接口为Serialization, ObjectInput, ObjectOutput, ThreadPool。

2、层次关系

  1. 在RPC中,Protocol是核心层,也就是只要有Protocol + Invoker + Exporter就可以完成非透明的RPC调用,然后在Invoker的主过程上Filter拦截点。
  2. Consumer和Provider是抽象概念,只是想让看图者更直观的了解哪些类分属于客户端与服务器端,不用Client和Server的原因是Dubbo在很多场景下都使用Provider, Consumer, Registry, Monitor划分逻辑拓普节点,保持统一概念。
  3. 而Cluster是外围概念,所以Cluster的目的是将多个Invoker伪装成一个Invoker,这样其它人只要关注Protocol层Invoker即可,加上Cluster或者去掉Cluster对其它层都不会造成影响,因为只有一个提供者时,是不需要Cluster的。
  4. Proxy层封装了所有接口的透明化代理,而在其它层都以Invoker为中心,只有到了暴露给用户使用时,才用Proxy将Invoker转成接口,或将接口实现转成Invoker,也就是去掉Proxy层RPC是可以Run的,只是不那么透明,不那么看起来像调本地服务一样调远程服务。
  5. 而Remoting实现是Dubbo协议的实现,如果你选择RMI协议,整个Remoting都不会用上,Remoting内部再划为Transport传输层和Exchange信息交换层,Transport层只负责单向消息传输,是对Mina,Netty,Grizzly的抽象,它也可以扩展UDP传输,而Exchange层是在传输层之上封装了Request-Response语义。
  6. Registry和Monitor实际上不算一层,而是一个独立的节点,只是为了全局概览,用层的方式画在一起。

3、模块简介

  1. dubbo-common 公共逻辑模块,包括Util类和通用模型。
  2. dubbo-remoting 远程通讯模块,相当于Dubbo协议的实现,如果RPC用RMI协议则不需要使用此包。
  3. dubbo-rpc 远程调用模块,抽象各种协议,以及动态代理,只包含一对一的调用,不关心集群的管理。
  4. dubbo-cluster 集群模块,将多个服务提供方伪装为一个提供方,包括:负载均衡, 容错,路由等,集群的地址列表可以是静态配置的,也可以是由注册中心下发。
  5. dubbo-registry 注册中心模块,基于注册中心下发地址的集群方式,以及对各种注册中心的抽象。
  6. dubbo-monitor 监控模块,统计服务调用次数,调用时间的,调用链跟踪的服务。
  7. dubbo-config 配置模块,是Dubbo对外的API,用户通过Config使用Dubbo,隐藏Dubbo所有细节。
  8. dubbo-container 容器模块,是一个Standlone的容器,以简单的Main加载Spring启动,因为服务通常不需要Tomcat/JBoss等Web容器的特性,没必要用Web容器去加载服务。

4、依赖关系

提供方和消费方都是通过注册中心来交互,提供方依赖注册中心来暴露需提供的接口,服务方通过注册中心来调用接口。提供方和注册方与注册中心之间是无状态联系的,也就是说它俩不论说挂掉了不会影响另一方的使用。这也是大部分生产/消费框架设计最科学的地方,双方进行无状态交互,互不干涉互不影响,软件设计的观察者模式也与此类似。

5、调用链

6、服务提供方提供服务的时序图

7、服务消费方消费服务时序图

三、实现细节

1、服务的解析

基于dubbo.jar内的META-INF/spring.handlers配置,Spring在遇到dubbo名称空间时,会回调DubboNamespaceHandler。所有dubbo的标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象。在ServiceConfig.export()或ReferenceConfig.get()初始化时,将Bean对象转换URL格式,所有Bean属性转成URL的参数。然后将URL传给Protocol扩展点,基于扩展点的Adaptive机制,根据URL的协议头,进行不同协议的服务暴露或引用。

2、提供者暴露服务

(1) 只暴露服务端口:

  • 在没有注册中心,直接暴露提供者的情况下,即:

    • <dubbo:service regisrty="N/A" /> or <dubbo:registry address="N/A" />
  • ServiceConfig解析出的URL的格式为:
    • dubbo://service-host/com.foo.FooService?version=1.0.0
  • 基于扩展点的Adaptive机制,通过URL的"dubbo://"协议头识别,直接调用DubboProtocol的export()方法,打开服务端口。

(2) 向注册中心暴露服务:

  • 在有注册中心,需要注册提供者地址的情况下,即:

    • <dubbo:registry address="zookeeper://10.20.153.10:2181" />
  • ServiceConfig解析出的URL的格式为:
    • registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode("dubbo://service-host/com.foo.FooService?version=1.0.0")
  • 基于扩展点的Adaptive机制,通过URL的"registry://"协议头识别,就会调用RegistryProtocol的export()方法,将export参数中的提供者URL,先注册到注册中心,再重新传给Protocol扩展点进行暴露:
    • dubbo://service-host/com.foo.FooService?version=1.0.0
  • 基于扩展点的Adaptive机制,通过提供者URL的"dubbo://"协议头识别,就会调用DubboProtocol的export()方法,打开服务端口。

3、消费方消费服务

(1) 直连引用服务:

  • 在没有注册中心,直连提供者的情况下,即:

    • <dubbo:reference url="dubbo://service-host/com.foo.FooService?version=1.0.0" />
  • ReferenceConfig解析出的URL的格式为:
    • dubbo://service-host/com.foo.FooService?version=1.0.0
  • 基于扩展点的Adaptive机制,通过URL的"dubbo://"协议头识别,直接调用DubboProtocol的refer()方法,返回提供者引用。

(2) 从注册中心发现引用服务:

  • 在有注册中心,通过注册中心发现提供者地址的情况下,即:

    • <dubbo:registry address="zookeeper://10.20.153.10:2181" />
  • ReferenceConfig解析出的URL的格式为:
    • registry://registry-host/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode("consumer://consumer-host/com.foo.FooService?version=1.0.0")
  • 基于扩展点的Adaptive机制,通过URL的"registry://"协议头识别,就会调用RegistryProtocol的refer()方法,基于refer参数中的条件,查询提供者URL,如:
    • dubbo://service-host/com.foo.FooService?version=1.0.0
  • 基于扩展点的Adaptive机制,通过提供者URL的"dubbo://"协议头识别,就会调用DubboProtocol的refer()方法,得到提供者引用。
  • 然后RegistryProtocol将多个提供者引用,通过Cluster扩展点,伪装成单个提供者引用返回。

4、服务者暴露服务过程图解

可以看到ServiceConfig类拿到对外提供服务的实际类ref,然后通过代理工厂类ProxyFactory类的getInvoker方法使用ref生成一个抽象代理对象AbstractProxyInvoker实例,到这一步就完成具体服务到Invoker的转化。接下来就是Invoker转换到Exporter的过程。

4、消费者消费服务过程图解

可以看到引用配置对象ReferenceConfig的init方法调用Protocol的refer方法生成Invoker实例(如上图中的红色部分),这是服务消费的关键。接下来把Invoker转换为客户端需要的接口。

四、总结

可以看到引用配置对象ReferenceConfig的init方法调用Protocol的refer方法生成Invoker实例(如上图中的红色部分),这是服务消费的关键。接下来把Invoker转换为客户端需要的接口。

1、dubbo的实现

Dubbo协议的Invoker转为Exporter发生在DubboProtocol类的export方法,它主要是打开socket侦听服务,并接收客户端发来的各种请求,通讯细节由Dubbo自己实现。

2、RMI的实现:

RMI协议的Invoker转为Exporter发生在RmiProtocol类的export方法,
它通过Spring或Dubbo或JDK来实现RMI服务,通讯细节这一块由JDK底层来实现,这就省了不少工作量。

关于dubbo的设计还有笔者还有很多需要学习的地方,想学习更过的dubbo技术可以去参考dubbo的官方API  http://dubbo.io/.

dubbo结构及通信简介的更多相关文章

  1. GO语言的进阶之路-go的程序结构以及包简介

    GO语言的进阶之路-go的程序结构以及包简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编辑,编译和运行 A,编辑 Go程序使用UTF-8编码的纯Unicode文本编写.大 ...

  2. Dubbo 分布式服务框架简介

    1.分布式服务框架 1.1 Dubbo 简介 Dubbo 是一个分布式服务框架,以及阿里巴巴内部的 SOA 服务化治理方案的核心框架.其功能主要包括:高性能 NIO 通讯及多协议集成,服务动态寻址与路 ...

  3. socket通信简介

    转:http://blog.csdn.net/xiaoweige207/article/details/6211577 “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的 ...

  4. 转:socket通信简介

    转:http://blog.csdn.net/xiaoweige207/article/details/6211577/ 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页 ...

  5. 【转】socket 通信简介

    转自:http://blog.csdn.net/xiaoweige207/article/details/6211577/ “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是 ...

  6. usb驱动的基本结构和函数简介【转】

    转自:http://blog.csdn.net/jeffade/article/details/7698404 几个重要的结构 struct--接口 struct usb_interface { /* ...

  7. springboot 集成 dubbo(一)简介

    一.简介 1,springboot 是 一款快速开发的框架,减少了开发人员对配置文件的操作.采用一些注解来取代xml配置文件. 注解包含预先封装的注解和开发人员自定义注解.同时使用Maven.Grad ...

  8. c# 与flash通信简介

    许久不曾写随笔,即使许久的怠惰,是该抬抬头,看看天了. 公司项目,项目要求是在winForm端先获取下位机的肌电信号采集数据,然后根据这些数据的变化来控制flash游戏,这样一些患者在flash游戏中 ...

  9. dubbo 笔记-XML配置文件简介

    <dubbo:service/> 服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心. eg.<dubbo:service r ...

随机推荐

  1. 电商的噩梦?实体商家的福音——VR全景智慧城市

    我们不知道未来网络购物的样子,但对当前电商平台的问题是清楚的.从消费者角度来看,网购的顾虑主要在于商品的质量难以保证.物流效率不够高,以及网络购物的"眼见不为实". 正因为可以很好 ...

  2. springMvc注解之@ResponseBody和@RequestBody

    简介 springmvc对json的前后台传输做了很好封装,避免了重复编码的过程,下面来看看常用的@ResponseBody和@RequestBody注解 添加依赖 springmvc对json的处理 ...

  3. 使用IDEA部署Myeclipse项目

    IDEA的下载和FREE注册 IDEA 下载地址:IDEA最新版本下载地址 IDEA 注册方法:注册方法 导入Myeclipse项目 IDEA主界面,选择Open,如下图所示 选择Myeclipse项 ...

  4. MSSQL-Scripter,一个新的生成T-SQL脚本的SQL Server命令行工具

    这里向大家介绍一个新的生成T-SQL脚本的SQL Server命令行工具:mssql-scripter.它支持在SQL Server.Azure SQL DB以及Azure SQL DW中为数据库生成 ...

  5. Spring Cloud 客服端负载均衡 Ribbon

    一.简介   Spring Cloud Ribbon 是一个基于Http和TCP的客服端负载均衡工具,它是基于Netflix Ribbon实现的.它不像服务注册中心.配置中心.API网关那样独立部署, ...

  6. JS中Node节点总结

    Node的三个基本属性: 1.nodeType:表明节点类型,1是元素节点,3是文本节点. 2.nodeName:  表明节点名称,元素节点为标签名,文本节点为#text. 3.nodeValue:表 ...

  7. 兼容ie浏览器的placeholder的几种方法

    项目中遇到的问题,试了几种方法,今天整理出来,如果有不合适的地方,希望大家多多提意见. 第一种方法是:使用html新增的属性 “data-”来实现的,实现的时候,input框没有使用placehole ...

  8. maven 创建后报错

    <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId& ...

  9. 黑马程序员:3分钟带你读懂C/C++学习路线

    随着互联网及互联网+深入蓬勃的发展,经过40余年的时间洗礼,C/C++俨然已成为一门贵族语言,出色的性能使之成为高级语言中的性能王者.而在今天,它又扮演着什么样重要的角色呢?请往下看: 后端服务器,移 ...

  10. ViewModel从未如此清爽 - 轻量级WPF MVVM框架Stylet

    Stylet是我最近发现的一个WPF MVVM框架, 在博客园上搜了一下, 相关的文章基本没有, 所以写了这个入门的文章推荐给大家. Stylet是受Caliburn Micro项目的启发, 所以借鉴 ...