当前位置: 首页 > 后端技术 > Java

一篇看懂Dubbo代码结构的文章

时间:2023-04-01 13:20:22 Java

整体设计图例:图中左侧浅蓝色背景为服务消费者使用的接口,右侧浅绿色背景为服务使用的接口provider,而中轴上的是双方使用的接口使用的接口。该图从下到上分为十层。每一层都是单向依赖的。右边的黑色箭头表示层与层之间的依赖关系。每一层都可以通过剥离上层来重复使用。其中,Service和Config层是API。所有其他层都是SPI。图中绿色小块是扩展接口,蓝色小块是实现类。图中只展示了用于关联各层的实现类。图中蓝色虚线为初始化过程,即启动时的汇编链,红色实线为方法调用过程,即运行时时序链,紫色三角箭头为继承。你可以把子类看成是父类的同一个节点,上面一行文字就是要调用的方法。各层说明Config配置层:对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接初始化配置类,也可以通过spring解析配置生成配置类Proxy服务代理层:服务接口透明代理,生成服务客户端Stub和Server-sideSkeleton,以ServiceProxy为中心,扩展接口为ProxyFactoryRegistryRegistry层:封装了服务地址的注册和发现,以服务URL为中心,扩展接口为RegistryFactory、Registry、RegistryServiceCluster路由层:封装了多个的路由和路由providers负载均衡,桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router、LoadBalanceMonitor监控层:RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory,Monitor、MonitorServiceProtocol远程调用层:封装RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker、ExporterExchange信息交换层:封装请求响应方式,同步转异步,以Request、Response为中心,扩展接口为Exchanger,ExchangeChannel,ExchangeClient,ExchangeServerTransport网络传输层:抽象mina和netty为统一接口,以Message为中心,扩展接口有Channel,Transporter,Client,Server,CodecSerialize数据序列化层:一些可复用的工具,扩展接口有Seri??alization,ObjectInput、ObjectOutput、ThreadPool关系表明,在RPC中,Protocol是核心层,即只要有Protocol+Invoker+Exporter就可以完成非透明的RPC调用,然后Filter拦截点在main调用者的过程。图中的Consumer和Provider是抽象的概念,只是为了让浏览者更直观的了解哪些类属于客户端和服务端。之所以没有使用Client和Server,是因为Dubbo使用Provider、Consumer、Registry、Monitor划分逻辑拓扑节点,保持统一的概念。而Cluster是一个外围概念,所以Cluster的目的是将多个Invoker伪装成一个Invoker,这样其他人只需要关注Protocol层的Invoker,增减Cluster不会影响其他层,因为只有一个提供否则,不需要集群。Proxy层封装了所有接口的透明代理,Invoker是其他层的中心。只有暴露给用户的时候,使用Proxy将Invoker转化为接口,或者将接口实现转化为Invoker,也就是去掉Proxy层RPC可以运行,但是不是那么透明,以及它看起来不像调用本地服务那样调用远程服务。Remoting实现是Dubbo协议的实现。如果选择RMI协议,则整个Remoting将不会被使用。Remoting分为Transport传输层和Exchange信息交换层。传输层只负责单向消息传输。对于Mina、Netty、Grizzly的抽象,还可以扩展UDP传输,Exchange层在传输层之上封装了Request-Response语义。Registry和Monitor其实不认为是一个层,而是一个独立的节点,只是为了一个全局的概览,分层绘制在一起。ModuleSubpackage模块说明:dubbo-common公共逻辑模块:包括Util类和公共模型。dubbo-remoting远程通信模块:相当于dubbo协议的实现,如果RPC使用RMI协议,则不需要使用该包。dubbo-rpc远程调用模块:抽象各种协议,动态代理,只包含一对一调用,不关心集群管理。dubbo-cluster集群模块:将多个服务提供者伪装成一个提供者,包括:负载均衡、容错、路由等。集群的地址列表可以静态配置,也可以由注册中心下发。dubbo-registry注册中心模块:基于注册中心发布的集群方式,对各种注册中心进行抽象。dubbo-monitor监控模块:统计服务调用次数、调用时间、调用链跟踪的服务。dubbo-config配置模块:是Dubbo的对外API,用户通过Config使用Dubbo,隐藏Dubbo的所有细节。dubbo-container容器模块:是一个Standlone容器,通过简单的Main加载Spring启动,因为服务通常不需要Tomcat/JBoss等web容器的特性,不需要使用web容器来实现加载服务。总的来说,分包是按照层级结构进行的。与层级结构不同的是,Container是一个服务容器,用于部署和运行服务,不在层中绘制。Protocol层和Proxy层都放在rpc模块中。这两层是rpc的核心。当不需要集群,即只有一个provider时,可以只用这两层来完成rpc调用。Transport层和Exchange层都放在remoting模块中,是rpc调用的通信基础。Serialize层放在common模块中,以便更好地重用。依赖图例说明:图中的小方块Protocol、Cluster、Proxy、Service、Container、Registry、Monitor代表层或模块,蓝色的表示和业务交互,绿色的只和Dubbo内部交互。图中背景方块Consumer、Provider、Registry、Monitor代表部署逻辑拓扑节点。图中蓝色虚线是初始化时的调用,红色虚线是运行时的异步调用,红色实线是运行时的同步调用。图中只包含了RPC层,没有包含Remoting层,Remoting作为一个整体是隐含在Protocol中的。调用链展开通用设计图红色调用链,如下:设计图,时序图如下:参考服务时序展开通用设计图左边的服务消费者指的是服务Green初始化链,时序图如下:领域模型在核心领域Dubbo的模型:Protocol是服务域,是Invoker暴露和引用的主要功能入口,负责Invoker的生命周期管理。Invoker是一个实体域,它是Dubbo的核心模型,其他模型都接近它,或者转化为它,它代表一个可执行体,可以向它发起invoke调用,它可能是本地实现,也可能是它be远程实现,可能是集群实现。Invocation是一个session域,保存着调用过程中的变量,比如方法名、参数等。基本设计原则采用Microkernel+Plugin模式。Microkernel只负责组装Plugin。Dubbo自身的功能也是通过扩展点来实现的,即Dubbo的所有功能点都可以被用户自定义的扩展替换。使用URL作为配置信息的统一格式,所有的扩展点都通过传递URL来携带配置信息。