前言
Dubbo Provider暴露服务的流程中,需要掌握几个核心抽象对象
- 过程中的重要类
- ServiceConfig:记录了Dubbo Service所有相关的配置信息。ServiceConfig作用
- DubboProtocol:以Dubbo协议的方式暴露服务,并以此为中心维护所有相关的动态服务数据。
- RegisterProtocol: 内部会加载具体的注册中心Register,例如:ZookeeperRegister。完成服务向注册中心注册的动作。
- ServiceConfig#loadRegistries:解析获得注册中心地址列表
- 过程中的重要对象
- com.alibaba.dubbo.common.URL: 服务发布的地址
- Invoker: 对原Service Interface进行了代理封装,屏蔽了具体Service Interface的差异,方便统一管理和调用。
- Exporter: 一个ServiceBean每向一个注册中心Register注册一次,就会生成已各Exporter。Exporter用于连接暴露服务的Url与本地Invoker的对应关系。
- ExporterMap: 记录着服务地址和Exporter的对应关系
- 来自Dubbo官方的几个架构设计图,先感觉下
ServiceBean核心流程
- Spring容器启动,带动Dubbo Bean配置解析以及Bean实例化。
- Dubbo启动
- 关键类:
- DubboNamespaceHandler
- ServiceBean
- ServiceConfig作用
- ServiceBean 继承了ServiceConfig,所有的Provider服务的Dubbo配置都在ServiceConfig中。
- Dubbo Service基本信息
- Dubbo Service参数配置
- 注册中心地址信息。对应ServiceConfig中的loadRegistries().
- ServiceBean 实现了InitializingBean, 实现了afterPropertiesSet()方法,在每个Dubbo Service Bean实例化后,在afterPropertiesSet()方法中进行所有Dubbo服务注册需要的操作。
- afterPropertiesSet()中前置代码都是在做一些配置校验和默认值设置,最后会执行export()方法注册暴露服务。
- afterPropertiesSet()
- export()
- doExport()
- doExportUrls()
- doExportUrlsFor1Protocol(DubboProtocol, regitsryURLs)
- DubboProtocol.export(wrapperInvoker)
- doExportUrlsFor1Protocol(DubboProtocol, regitsryURLs)
- doExportUrls()
- doExport()
- export()
- doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List
registryURLs) 是真正执行export暴露服务的代码区
DubboProtocol#Export核心流程
1 | public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException { |
DubboProtocol核心数据
1 | public class DubboProtocol extends AbstractProtocol { |
1 |
|
Dubbo Service是哪个时机注册到注册中心的?
有关注到这个章节内容的小伙伴,说明你此时可能也还没想通吧,请听我道来。
这里会涉及到Dubbo的SPI机制,Dubbo 有好几个利用SPI+动态代理+Filter的处理责任链模式,ProtocolFilterWrapper.java算一个。
- Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
在Dubbo源码中,Dubbo有自行注册几个protocol SPI (这里只列举Dubbo服务注册相关的)
- SPI机制用法详见
- Dubbo Protocol SPI扩展详见
- RegistryProtocol SPI:
- 注册位置:dubbo-registry-api包,resources下的com.alibaba.dubbo.rpc.Protocol
- 注册位置:dubbo-registry-zookeeper包,resources下的com.alibaba.dubbo.register.RegistryFactory
其实,在ServiceConfig中拿到的全局protocol并不直接是DubboProtocol,而是一串Protocol,DubboProtocol只是其中之一,这些Protocol会以责任链的方式逐一被调用
所以,在doExportUrlsFor1Protocol中protocol.export(…)时,会先执行DubboProtocol#export,再执行RegisterProtocol#export,各司其职。
RegisterProtocol中会根据Dubbo Service配置的register地址类型来决定加载哪个具体的RegisterFactory
1 | public void register(URL registryUrl, URL registedProviderUrl) { |
Netty Server
当DubboProtocol.export.openServer()时,就是在本地启动Dubbo Service的Server服务并启动监听。
实现上是通过Exchanger拿到被配置的信息交换层的实现套件(一般是Netty)。
- 获取一个服务端口,使用NettyServer绑定并监听,并设置Server监听事件处理回调为:DubboProtocol#requestHandler
- Exchanger.bind的实际对象可配置,对应dubbo-remoting-api包
1 | public class NettyServer extends AbstractServer implements Server { |
ServiceConfig作用(见代码注释)
1 | public class ServiceConfig<T> extends AbstractServiceConfig { |
Dubbo 启动
Spring容器启动,带动Dubbo Bean配置实例化。Dubbo Bean配置来自于Dubbo Provider XML 文件。
1 | public class DubboNamespaceHandler extends NamespaceHandlerSupport { |
- 具体详见笔记:Dubbo源码解析-Spring Bean注册
ServiceBean实例化
1 | public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener<ContextRefreshedEvent>, BeanNameAware { |
ServiceBean 继承了ServiceConfig,所有的Provider服务的Dubbo配置都在ServiceConfig中。
ServiceBean 实现了InitializingBean, 实现了afterPropertiesSet()方法,在每个Dubbo Service Bean实例化后,进行暴露服务的相关操作。
afterPropertiesSet()中前置代码都是在做一些配置校验和默认值设置,最后会执行export()方法注册暴露服务。
1 | public void afterPropertiesSet() throws Exception { |
Export暴露服务
- export()方法会完成后续服务注册的所有流程
1 | public synchronized void export() { |