Dubbo架构与底层实现

一、Dubbo的设计角色

(1)  系统角色

Provider: 暴露服务的服务提供方。

Consumer: 调用远程服务的服务消费方。

Registry: 服务注册与发现的注册中心。

Monitor: 统计服务的调用次调和调用时间的监控中心。

Container: 服务运行容器。

(2)  调用关系

服务容器负责启动,加载,运行服务提供者。

服务提供者在启动时,向注册中心注册自己提供的服务。

服务消费者在启动时,向注册中心订阅自己所需的服务。

注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心 

二、Dubbo是如何架构的

Dubbo的总体架构如图所示:


框架分层架构中,各个层次的设计要点:

服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。

配置层(Config):对外配置接口,以ServiceConfigReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。

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

服务注册层(Registry):封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactoryRegistryRegistryService。可能没有服务注册中心,此时服务提供方直接暴露服务。

集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为ClusterDirectoryRouterLoadBalance。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。

监控层(Monitor):RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactoryMonitorMonitorService

远程调用层(Protocol):封将RPC调用,以InvocationResult为中心,扩展接口为ProtocolInvokerExporterProtocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。

信息交换层(Exchange):封装请求响应模式,同步转异步,以RequestResponse为中心,扩展接口为ExchangerExchangeChannelExchangeClientExchangeServer

网络传输层(Transport):抽象minanetty为统一接口,以Message为中心,扩展接口为ChannelTransporterClientServerCodec

数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization ObjectInputObjectOutputThreadPool

三、Dubbo的底层实现

1)协议支持

Dubbo支持多种协议,如下所示:

Dubbo协议

Hessian协议

HTTP协议

RMI协议

WebService协议

Thrift协议

Memcached协议

Redis协议

在通信过程中,不同的服务等级一般对应着不同的服务质量,那么选择合适的协议便是一件非常重要的事情。你可以根据你应用的创建来选择。例如,使用RMI协议,一般会受到防火墙的限制,所以对于外部与内部进行通信的场景,就不要使用RMI协议,而是基于HTTP协议或者Hessian协议。

RMI是java语言本身提供的远程通讯协议,稳定高效,是EJB的基础。但它只能用于JAVA程序之间的通讯。

Hessian是caucho公司提供的开源协议,基于HTTP传输,服务端不用开防火墙端口。协议的规范公开,可以用于任意语言。

Web service是连接异构系统或异构语言的首选协议,它使用SOAP形式通讯,可以用于任何语言,目前的许多开发工具对其的支持也很好。

2)默认使用Dubbo协议

连接个数:单连接

连接方式:长连接

传输协议:TCP

传输方式:NIO异步传输

序列化:Hessian二进制序列化(如下图所示)


适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要使用dubbo协议传输大文件或超大字符串

使用场景:常规远程服务方法调用

从上面的适用范围总结,dubbo适合小数据量大并发的服务调用,以及消费者机器远大于生产者机器数的情况,不适合传输大数据量的服务比如文件、视频等,除非请求量很低。

3Dubbo源码模块图

Dubbo以包结构来组织各个模块,各个模块及其关系,如图所示:


可以通过Dubbo的代码(使用Maven管理)组织,与上面的模块进行比较。简单说明各个包的情况:

dubbo-common 公共逻辑模块,包括Util类和通用模型。

dubbo-remoting 远程通讯模块,相当于Dubbo协议的实现,如果RPCRMI协议则不需要使用此包。

dubbo-rpc 远程调用模块,抽象各种协议,以及动态代理,只包含一对一的调用,不关心集群的管理。

dubbo-cluster 集群模块,将多个服务提供方伪装为一个提供方,包括:负载均衡、容错、路由等,集群的地址列表可以是静态配置的,也可以是由注册中心下发。

dubbo-registry 注册中心模块,基于注册中心下发地址的集群方式,以及对各种注册中心的抽象。

dubbo-monitor 监控模块,统计服务调用次数,调用时间的,调用链跟踪的服务。

dubbo-config 配置模块,是Dubbo对外的API,用户通过Config使用Dubbo,隐藏Dubbo所有细节。

dubbo-container 容器模块,是一个Standalone的容器,以简单的Main加载Spring启动,因为服务通常不需要Tomcat/JBossWeb容器的特性,没必要用Web容器去加载服务。

四、服务暴露和消费的详细过程

1)服务提供者暴露一个服务的详细过程

服务提供者暴露服务的主过程:


首先ServiceConfig类拿到对外提供服务的实际类ref(如:HelloWorldImpl),然后通过ProxyFactory类的getInvoker方法使用ref生成一个AbstractProxyInvoker实例,

到这一步就完成具体服务到Invoker的转化。接下来就是Invoker转换到Exporter的过程。

Dubbo处理服务暴露的关键就在Invoker转换到Exporter的过程(如上图中的红色部分),下面我们以DubboRMI这两种典型协议的实现来进行说明:

Dubbo的实现

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

RMI的实现

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

2)服务消费者消费一个服务的详细过程

服务消费的主过程:


首先ReferenceConfig类的init方法调用Protocolrefer方法生成Invoker实例(如上图中的红色部分),这是服务消费的关键。

接下来把Invoker转换为客户端需要的接口(如:HelloWorld)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值