分布式服务框架实现机制--Dubbo

简述:Dubbo是一款由阿里开源的RPC分布式服务调用框架,主要运用于高并发小数据量的 rpc 调用,在大数据量下的性能表现并不好,建议使用 rmi 或 http 协议

 

一、什么是RPC【远程过程调用协议】

系统由单一的应用架构发展为多个应用架构后,应用间的交互不可避免,这时将核心业务线整理出来,各应用的被外应用调用的处理可以整理为一个服务,通过注册中心统一管理,各应用按需注册调用,只需关注自己实际处理部分。简言之,RPC使得程序能够像访问本地系统资源一样,去访问远端系统资源。比较关键的一些方面包括:通讯协议、序列化、资源(接口)描述、服务框架、性能、语言支持等。

详情可参考:https://zhuanlan.zhihu.com/p/98145736

二、什么是Dubbo

随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA),也因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架。就这样为分布式系统的服务治理框架就出现了,Dubbo 也就这样产生了。

二、组件:

1、PRC架构组件

一个基本的RPC架构里面应该至少包含以下4个组件:

(1)、客户端(Client):服务调用方(服务消费者)

(2)、客户端存根(Client Stub):存放服务端地址信息,将客户端的请求参数数据信息打包成网络消息,再通过网络传输发送给服务端

(3)、服务端存根(Server Stub):接收客户端发送过来的请求消息并进行解包,然后再调用本地服务进行处理

(4)、服务端(Server):服务的真正提供者

2、Dubbo 的整体架构设计分层:
(1)、接口服务层(Service):该层与业务逻辑相关,根据 provider 和 consumer 的业务设计对应的接口和实现

(2)、配置层(Config):对外配置接口,以 ServiceConfig 和 ReferenceConfig 为中心

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

(4)、服务注册层(Registry):封装服务地址的注册和发现,以服务 URL 为中心,扩展接口为 RegistryFactory、Registry、RegistryService

(5)、路由层(Cluster):封装多个提供者的路由和负载均衡,并桥接注册中心,以Invoker 为中心,扩展接口为 Cluster、Directory、Router 和 LoadBlancce

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

(7)、远程调用层(Protocal):封装 RPC 调用,以 Invocation 和 Result 为中心,扩展接口为 Protocal、Invoker 和 Exporter

(8)、信息交换层(Exchange):封装请求响应模式,同步转异步。以 Request 和Response 为中心,扩展接口为 Exchanger、ExchangeChannel、ExchangeClient 和 ExchangeServer
(9)、网络传输层(Transport):抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 Channel、Transporter、Client、Server 和 Codec
(10)、数据序列化层(Serialize):可复用的一些工具,扩展接口为 Serialization、ObjectInput、ObjectOutput 和 ThreadPool

分布式服务框架实现机制--Dubbo_第1张图片

二、实现流程

1、服务暴露流程:https://aobing.blog.csdn.net/article/details/108345229

(1)ServiceBean:服务先根据dubbo协议中的server或provider标签配置,初始化对应的bean对象ref

(2)ServiceBean.onApplicationEvent :当Spring IOC容器刷新完成后会调用 onApplicationEvent 方法,而这个方法里面做的就是服务暴露,这就是服务暴露的启动点。

(3)ServiceConfig.export:判断是否需要暴露服务,根据暴露范围,配置构建对应的暴露服务url,把application、config、path、protocol、运行参数等拼接到URL中,后续在每个协议中还会拼接不同协议的path、group、version。

(4)ServiceConfig.doExportUrlsFor1Protocol :根据 URL 在每个协议中进行服务暴露,

exportLocal:本地暴露

如果为本地服务Injvm,则会通过InjvmProtocol 的export进行暴露。在SPI#createExtension中,我们看到了Extension的创建,是wrapperClass装饰的,而InjvmProtocol是由org.apache.dubbo.rpc.protocol.ProtocolFilterWrapperorg.apache.dubbo.qos.protocol.QosProtocolWrapperorg.apache.dubbo.rpc.protocol.ProtocolListenerWrapper这三个装饰的。调用的时候,会先调用ProtocolListenerWrapperexport方法,然后会调用QosProtocolWrapperexport方法,然后是ProtocolFilterWrapperexport方法,这里会获取filter,最后是InjvmProtocolInjvmProtocol。从InjvmProtocolProtocolFilterWrapperQosProtocolWrapperexport方法,都执行完后,就开始创建一个ListenerExporterWrapper,负责监听export和unexport。

exportRomote:远程服务暴露

RegistryProtocol.export:如果不为本地服务injvm且有注册中心则会通过RegistryProtocol的export进行远程服务暴露,如果有监控中心则会在注册好之后通知监控中心

1)获取注册中心的地址

2)获取服务方地址

3)订阅覆盖的服务方的地址

4)监听服务方

5)调用protocol的export生成对应协议的exporter:

Dubbo 协议的 export 主要就是根据 URL 构建出 key(例如有分组、接口名端口等等),然后 key 和 invoker 关联,关联之后存储到 DubboProtocol 的 exporterMap 中,通过exporter中的openServer,创建对应的ExchangeServer监听服务器监听客户端请求,默认是Netty,初始化对应的Handler如心跳、解码等,最后实现SerializationOptimizer接口的先实例化。

6)创建zkclient,连接zk,注册服务,并订阅服务方

7)通知已暴露服务

8)返回DestroyableExporter

分布式服务框架实现机制--Dubbo_第2张图片

  • 首先 ServiceConfig 类拿到对外提供服务的实际类 ref(如:DemoServiceImpl);
  • 然后通过 JavassistProxyFactory 类的 getInvoker 方法将 ref 封装到一个 AbstractProxyInvoker 实例;
  • 最后通过 InjvmProtocol(本地暴露)和 DubboProtocol(远程暴露)将AbstractProxyInvoker 实例转换成 InjvmExporter 和 DubboExporter。

https://www.jianshu.com/p/1e95c541d1e6#comments
 

三、相关拓展机制:SPI

SPI的全称是 Service Provider Interface,它是一种服务发现机制,它通过在 classPath 路径下的 META-INF/services 文件夹查找服务实现,自动加载文件里所定义的接口实现类。

SPI 的底层实现基本使用了反射机制,通过全类名实例化接口实现,从而发起调用。

SPI 机制为很多框架扩展提供了可能,比如在Dubbo、JDBC中都使用到了SPI机制。

和dubboSPI 相关的解析:https://www.jianshu.com/p/318857b1662f

可以说dubbo的很多功能都是通过拓展以一种可插拔的方式进行组装,同时也方便开发者对框架进行拓展

https://www.cnblogs.com/jmcui/p/10962292.html

 

你可能感兴趣的:(微服务学习,dubbo,java,rpc,分布式)