版本
2.5.7
服务暴露过程过程
dubbo的服务注册、调用等都是通过SPI实现的,即都需要通过ExtensionLoader来加载,且均为单例。
1、只暴露服务端口
在没有注册中心,直接暴露提供者的情况下 , ServiceConfig 解析出的 URL 的格式为:
dubbo://service-host/com.foo.FooService?version=1.0.0 。
基于扩展点自适应机制,通过 URL 的 dubbo:// 协议头识别,直接调用 DubboProtocol 的
export() 方法,打开服务端口。
2、向注册中心暴露服务
在有注册中心,需要注册提供者地址的情况下 , ServiceConfig 解析出的 URL 的格式为:
registry://registry-host/com.alibaba.dubbo.registry.RegistryService?
export=URL.encode("dubbo://service-host/com.foo.FooService?version=1.0.0") ,
基于扩展点自适应机制,通过 URL 的 registry:// 协议头识别,就会调用 RegistryProtocol 的
export() 方法,将 export 参数中的提供者 URL,先注册到注册中心。
再重新传给 Protocol 扩展点进行暴露: dubbo://service-host/com.foo.FooService?
version=1.0.0 ,然后基于扩展点自适应机制,通过提供者 URL 的 dubbo:// 协议头识别,就会调
用 DubboProtocol 的 export() 方法,打开服务端口。
3、详细流程
程序启动后,加载到ServiceConfig
类,执行doExport
方法:
- 传入的类是否为接口,接口中是否存在配置的方法;
- 引用
ref
是否为空,且是否为接口的实例; - 检查是否有应用配置;
- 检查是否有注册中心配置;
- 检查是否有协议配置;
- 执行
doExportUrls
方法。
在doExportUrls
中,通过loadRegistries
方法将将配置转换为URL:
- 获取注册地址;
- 通过
ExtensionLoader
加载RegistryFactory
; - 将之前的配置转为URL,此时协议为registry://。
接下来将协议配置和生成的URL一起传入doExportUrlsFor1Protocol
方法中:
- 获取dubbo配置的IP和端口,若未配置,则取本地IP和按递增取的可用端口;
- 再次组装URL,此时协议为dubbo://(根据配置)。
- 根据scope,选择暴露本地和远程服务
暴露服务的时候,默认使用的是JavassistProxyFactory
生成invoker
,并export
出去,实际上就是类似打开一个Socket服务的概念。