Dubbo源码分析(11):服务发布

服务发布是服务提供方向注册中注册服务过程,以便服务消费者从注册中心查阅并调用服务。

服务发布方在spring的配置文件中配置以下:git

<bean id="demoService"class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />

上面是在spring中配置的服务的具体实现,是spring中的一个普通的beangithub

<dubbo:serviceinterface="com.alibaba.dubbo.demo.DemoService" ref=”demoService”/>

上面的配置spring容器在启动的过程当中会解析自定义的schema元素dubbo转换成实际的配置实现ServiceBean ,并把服务暴露出去。spring

 

ServiceConfig.doExportUrls()执行具体的export过程

 

1. loadRegistries(true)缓存

checkRegistry若是xml中没有配置注册中,从dubbo.properties中读取配置,构建RegistryConfig对象并赋值app

构建注册中心URL统一数据模式集合List<registryUrl>负载均衡

2. 由于dubbo支持多协议配置,遍历全部协议分别根据不一样的协议把服务export到不一样的注册中心上去ide

a) 判断是不是泛型暴露ui

b) 根据协议构建暴露服务的统一数据模型URL编码

c) 配置的了monitor加载monitor,并给URL设置MONITOR_KEYurl

d) 给注册中regitryUrl设置EXPORT_KEY值为前面构建的暴露服务url

e) 根据服务具体实现,实现接口以及regitryUrl从代理工厂ProxyFactory获取代理Invoker(继承于AbstractProxyInvoker),它是对具体实现的一种代理

f) Protocol.export(invoker) 暴露服务invoker

Invoker包含上一步传入的RegistryUrl, registryUrl的protocol值为registry

ProtocolListenerWrapper和ProtocolFilterWrapper对于协议为REGISTRY_PROTOCOL直接跳过,最终由RegistryProtocol处理export的过程

 

RegistryProtocol暴露服务过程

这里传入的Invoker是由RegistryUrl从ProxyFactory获得的Invoker

1. 从Invoker获取providerUrl,在获取cacheKey, 根据cacheKey获取本地缓存的ExporterChangeableWrapper(exporter代理,创建返回的exporter与protocol export出的exporter的对应关系), 若是存在返回。

2. 若是不存在,根据传入的 Invoker获取providerUrl, 在构建InvokerDelegete(originInvoker, providerUrl)

3. Protocol.exprot(invokerDelegete) 根据providerUrl 的协议(通常是dubbo协议)经过Protocol的设配类暴露务,获得exporter

4. 利用providerUr导出的exporter和invoker构建对象ExporterChangeableWrapper缓存到本地

5. 由Invoker获得registryUrl。

 在根据registryUrl从RegistryFactory获取Registry, 获取RegistryUrl的注册中心协议,这里咱们拿zooKeeper协议为例。由dubbo的扩展机制获得的是ZookeeperRegistryFactory,获得注册器为ZookeeperRegistry

6. 由Invoker获取ProviderUrl在去除不须要在注册中心看到的字段获得registryProviderUrl

7. 注册中心(ZookeeperRegistry)注册registryProviderUrl

Registry.register(registryProviderUrl)

8. 由registryProviderUrl获取overrideSubscribeUrl,在构建OverrideListener

9. registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener) 注册中心订阅这个url, 用来当数据变化通知从新暴露, 哪zookeeper为例,暴露服务会在zookeeper生成一个节点,当节点发生变化的时候会触发overrideSubscribeListener的notify方法从新暴露服务

10.      构建并返回一个新的exporter实例

 

DubboProtocol暴露服务的过程

1. 从invoker获取统一数据模型url

2. 由url构建serviceKey(通常由端口,接口名,版本,group分组)

如:com.alibaba.dubbo.demo.DemoService:20880 这个是由接口和端口组成的

3. 构建DubboExporter放入本地map作缓存

4. 根据url openserver。 查找本地缓存以key为url.getAddress若是没有ExchangeServer建立。设置heartbeat时间,设置编码解码协议

根据url和ExchangeHandler  绑定server并返回(具体如何绑定专题介绍)

5. 返回DubboExporter对象

 

官方文档序列图

注册/注销服务
服务的注册与注销,是对服务提供方角色而言,那么注册服务与注销服务的时序图,如图所示:

服务订阅/取消
为了知足应用系统的需求,服务消费方的可能须要从服务注册中心订阅指定的有服务提供方发布的服务,在获得通知可使用服务时,就能够直接调用服务。反过来,若是不须要某一个服务了,能够取消该服务。
下面看一下对应的时序图,如图所示:

服务消费方发起远程调用的底层通讯

服务提供方接收请求并响应的底层通讯

 

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

  • Dubbo协议
  • Hessian协议
  • HTTP协议
  • RMI协议
  • WebService协议
  • Thrift协议
  • Memcached协议
  • Redis协议

在通讯过程当中,不一样的服务等级通常对应着不一样的服务质量,那么选择合适的协议即是一件很是重要的事情。你能够根据你应用的建立来选择。例如,使用RMI协议,通常会受到防火墙的限制,因此对于外部与内部进行通讯的场景,就不要使用RMI协议,而是基于HTTP协议或者Hessian协议。

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

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

  • 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 容器模块,是一个Standalone的容器,以简单的Main加载Spring启动,由于服务一般不须要Tomcat/JBoss等Web容器的特性,不必用Web容器去加载服务。

参考连接

相关文章
相关标签/搜索