Dubbo原理的实现之服务的暴露
首先由于博主的精力和知识有限,我这里是站在大佬的肩膀上和自己的资源来更好的为大家清晰的梳理一下Dubbo的源码的实现流程,具体的可以自己去Debug来去过一下流程。一共分为几个大步骤,然后每个大步骤下面再继续拆分为具体的核心功能的小步骤。
先放一个暴露本地服务的时序图:其实总的来说就这6大步,但是我具体又分了10小步来完成的
(1)暴露本地服务
(2)暴露远程服务
(3)启动Netty
(4)连接到Zookeeper服务器
(5)到Zookeeper注册
(6)监听Zookeeper服务器
- 其实第一步就是根据我们在XMl中配置的文件,对<dubbo: >标签的bean进行解析,然后注册的Spring容器中,供后面使用
- 然后当Spring 容器发布刷新事件的时候,会触发 ServiceBean 的 onApplicationEvent()方法,然后执行方法中的export()方法,这个方法是真正dubbo开始暴露本地方法的开始
- 然后进入export()之后是检查,没有的问题的话,就执行doExport()方法,然后又是一顿检查,检查提供者是不是为空、有没有初始化、接口名称是不是合法,然后没问题的话,再去执行 doExportUrls()方法,暴露服务。
- 进入 doExportUrls()方法之后,然后是加载注册中心的链接,遍历是那种调用方式(比如dubbo协议、dubbo直连),然后下一步是调用这个方法doExportUrlsFor1Protocol()组装URL。
- doExportUrlsFor1Protocol()方法中的这个过程的核心就是为了让从本地过来的一些核心参数转换为URL,这样更方便在网络中进行传输,比如把版本、时间戳、方法名以及各种配置对象的字段信息、上下文路径、主机名以及端口号等信息都放到URL中
- 然后是继续执行这个方法doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List registryURLs)的第二个重要的部分,把服务导出到本地JVM还是远程,会根据URL中scope参数决定导出服务的方式scope = none,不导出服务scope != remote,导出到本地scope != local,导出到远程。
- 然后是由ProxyFactory的一个代理工厂调用getInvoker(T proxy, Class type, URL url)方法来创建一个Invoker。其实这个Invoker就是一个包含了本地要暴露的代理对象(比如代理对象生成的代理类UserServiceImpl)、类型信息和上一步包装好的URL信息,就是一个执行者的完整信息对象,然后在进行包装成wrapperInvoker对象进行暴露出去,下一步调用export()方法
- 然后是通过Protocol.export(wrapperInvoker)把这个完成的Invoker对象暴露出去,这里使用了Java的SPI机制进行获取到的Protocol对像。只要一调用exporter就会生成一个Exporter对象,然后会使用下面的DubboProtocol对象进行暴露(先拿到注册中心的URL地址),其实也就是在进行一次Export()调用,然后会得到一个DubboExporter对象,使用是dubbo协议
- 然后通过DubboExporter去进行调用openServer()方法去开启服务器,因为刚开始没有服务器,所以需要创建一个ExchangeServer对象,然后继续进行通过bind()方法进行绑定对应的url。(然后一直进去发现其实调用的还是Netty的底层实现),然后启动服务器,监听端口
- 然后是把提供者的注册信息注册到ProviderConsumerRegTable对象中进行维护。
这里附上一张大概的流程图:
二次补充的,URL在Invoker对象中的URL对象都有哪些字段:
private final String protocol;
private final String username;
private final String password;
private final String host;
private final int port;
private final String path;
private final Map<String, String> parameters;
private transient volatile Map<String, Number> numbers;
private transient volatile Map<String, URL> urls;
private transient volatile String ip;
private transient volatile String full;
private transient volatile String identity;
private transient volatile String parameter;
private transient volatile String string;
参考文章:
视频:https://www.bilibili.com/video/av30612478/?p=27
官网文档:http://dubbo.apache.org/zh-cn/docs/source_code_guide/export-service.html
大牛博客:https://www.imooc.com/article/266672