Dubbo 框架设计
该图描述了服务注册中心、服务提供方、服务消费方、服务监控中心之间的调用关系:
- 服务提供者(Provider):暴露服务的服务提供方。服务提供者在启动时完成以下步骤进行服务暴露:
- 本地暴露:创建Netty服务端NettyServer,启动并监听配置文件中指定的Dubbo服务端口20880,等待消费者客户端发送远程调用当前服务的请求;
- 注册服务信息到本地缓存:将服务信息注册到提供者注册表(本地缓存
Map
)中; - 注册服务信息到注册中心:向注册中心注册自己提供的服务信息,例如在ZooKeeper的Dubbo节点下创建提供的服务节点,该节点包含该服务的接口名、Provider服务端(通常为NettyServer)的URL等信息;服务信息将被保存成
Map
结构:服务名 : List<URL>
。
- 服务消费者(Consumer): 调用远程服务的服务消费方。服务消费者在启动时,完成以下步骤进行服务引用:
- 获取注册中心地址并据此创建ZooKeeper注册中心类
registry
; - 根据服务名称从注册中心
registry
订阅服务的URL列表List<URL>
(只订阅当前工程引用的服务,其他服务不订阅); - 获取到服务URL信息后,创建
NettyClient
客户端与其进行通讯,并创建invoker
(包含了远程服务的信息,后续使用其进行远程服务调用); - 将
invoker
保存到消费者的本地缓存Map
中,这样即使ZooKeeper宕机本地工程也能使用缓存中的invoker
调用远程服务。
- 获取注册中心地址并据此创建ZooKeeper注册中心类
- 服务消费者在进行服务调用时将进行以下步骤:
- 使用服务的代理对象调用方法时将逐层调用其内嵌套的多个不同功能的
invoker
,基于软负载均衡算法,从服务URL列表中选择其中的一台提供者进行远程调用; - 多层
invoker
调用后将创建出Netty客户端NettyClient
与服务端NettyServer
进行通讯; - 将要调用的接口名、方法名和方法参数等信息经过编码序列化后发送给
NettyServer
,服务端收到该请求后创建目标服务对应的代理对象执行服务方法,待其执行完毕后再将方法的返回结果发送给客户端; - 远程调用原理:选择其中的某一个URL作为目标服务端
NettyServer
,创建NettyClient
与其进行通讯,将要执行的服务接口名、方法名、方法参数类型列表与方法值列表发送给NettyServer,令其创建代理对象调用该方法,从而实现远程调用目标方法。如果选中的服务器调用失败,再选另一台调用。
- 使用服务的代理对象调用方法时将逐层调用其内嵌套的多个不同功能的
- 注册中心(Registry):
- 注册中心负责保存服务提供者发来的服务信息,同时在消费者发来订阅请求时返回服务提供者地址列表(包含ip/port等信息)给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 当注册中心检测到有Dubbo提供者宕机时,将从节点中删除该提供者信息(超时检测机制),同时通知所有消费者节点信息发生改变,修改消费者本地缓存中的服务数据(使用ZooKeeper里的监听机制,在消费者从注册中心订阅时就绑定监听了注册中心服务节点信息改变事件)
- 监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
- 框架容器(Container):Dubbo容器(Spring容器)。
图中线条代表含义:
- 紫色虚线代表Dubbo容器启动时执行的步骤,先后为:
0.start
:启动Dubbo容器1.register
:服务提供者在注册中心内注册信息(服务端的ip地址和端口号等信息)2.subscribe
:服务消费者向注册中心订阅所有服务提供者的信息
- 蓝色虚线代表异步执行,当注册中心发现服务提供者发生改变时,会通知服务消费者该变化。服务提供者和服务消费者会定期向监控中心发送数据;
- 蓝色实线代表服务消费者同步执行服务提供者的方法。
Dubbo 整体设计图: