Dubbo服务暴露原理解析,带你手撕源码

1.概述

本文将一步一步的分析Dubbo服务暴露过程的源码,探究其实现的过程,选择的Dubbo版本是2.7.8。

测试代码如下:

@Test
public void openService() throws IOException {
    // 服务配置
    ServiceConfig serviceConfig = new ServiceConfig();
    // 应用
    ApplicationConfig app = new ApplicationConfig("coderead-server");
    serviceConfig.setApplication(app);
    // 协议
    ProtocolConfig protocol = new ProtocolConfig("dubbo");
    protocol.setPort(8080);
    serviceConfig.setProtocol(protocol);
    // 注册中心
    RegistryConfig registry = new RegistryConfig("zookeeper://127.0.0.1:2181");
    serviceConfig.setRegistry(registry);
    // 接口
    serviceConfig.setInterface(UserService.class);
    // 实现
    serviceConfig.setRef(new UserServiceImpl(8080));
    // 开启服务
    serviceConfig.export();
    System.in.read();
}

测试代码前面的部分就是设置服务的一些配置信息

服务的暴露是通过serviceConfig.export()来完成的,下面将分析export的执行过程,看看它究竟做了哪些事情。

2.服务暴露源码分析

ServiceConfig.export()

在这里插入图片描述
初始化服务的一些元信息,然后调用doExport()

ServiceConfig.doExport()

在这里插入图片描述
判断是否该服务已经暴露过,如果暴露过了则不再进行暴露,若没有则会调用doExportUrls()。

ServiceConfig.doExportUrls()

在这里插入图片描述
首先获得服务注册器,当前的服务注册器中的内容如下:
在这里插入图片描述
仅有两个dubbo自带的两种服务,一个是心跳服务EchoService,另一个是GenericService,提供泛化接口,用来进行泛化调用。这两个服务这里暂时不做说明,本文的重点不在这里。

执行完第二行代码后,服务注册器当中多了我们想要暴露的服务UserService,服务中有服务的描述,记录了服务的名字、服务的接口类型,服务的方法等信息。
在这里插入图片描述
第三行代码是往服务注册器当中注册服务提供者,执行之后repository如下,提供者记录了服务的实例、元数据、服务配置信息等。
在这里插入图片描述
之后获取用于注册的url,此例子中只有一个zookeeper注册中心。
在这里插入图片描述
for循环,遍历protocols协议,这里也说明了dubbo支持多协议,可以将一个服务暴露不同协议的服务。

调用doExportUrlsFor1Protocol(protocolConfig, registryURLs)

ServiceConfig.doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List< URL > registryURLs)

该方法的逻辑很长,暂时不用去深究细节,仅仅关注服务暴露的部分。
在这里插入图片描述
获取该url中配置的scope,根据这个参数有两种暴露可以选择,一种是本地暴露,另一个是远程暴露

本地暴露
在这里插入图片描述
在这里插入图片描述
构建一个InjvmExporter,不需要开启netty服务,相当提供一个在本地可调用服务。

远程暴露
在这里插入图片描述
基于代理工厂将接口的实现类ref封装成Invoker对象,然后调用Protocol的export方法,经过一系列的包装类,调用RegistryProtocol中的export方法。

RegistryProtocol.export(final Invoker< T > originInvoker)

在这里插入图片描述
doLocalExport真正执行开启服务并暴露服务的方法。最终会调用到DubboProtocol中的export。

RegistryProtocol 此处的作用就是等服务开启暴露完毕后,将服务的地址注册到注册中心当中。此例子中就是将服务的地址注册到zookeeper。

DubboProtocol.export(Invoker< T > invoker)

在这里插入图片描述
基于url获取服务的key,也就是服务的全限定类名:端口号

将Invoker封装成DubboExporter,保存在exporterMap当中。

然后调用openServer(url)开启服务。

DubboProtocol.openServer(URL url)

在这里插入图片描述
serverMap当中还没有当前的协议服务ProtocolServer,所以会调用createServer来构建一个协议服务。

DubboProtocol.createServer(URL url)

在这里插入图片描述
协议url中设置一些参数,比如心跳服务的周期,默认1分钟等。

获取远程路由服务,默认使用netty

调用Exchangers.bind 构建协议服务。
在这里插入图片描述
参数校验,然后获取Exchanger调用bind
在这里插入图片描述
调用Transporters.bind
在这里插入图片描述
获取Transporter,然后调用bind方法

NettyTransporter.bind(URL url, ChannelHandler handler)

最终来到NettyTransporter当中的bind
在这里插入图片描述
基于url和ChannelHandler开启netty服务。
在这里插入图片描述
调用父类的构造方法
在这里插入图片描述
属性的设置,然后调用doOpen,实现真正开启netty服务的方法。

NettyServer.doOpen()

在这里插入图片描述
学过netty的应该比较熟悉这段代码,初始化并开启了一个netty服务,服务就这样暴露出去了。
构建好的服务会保存在DubboProtocol的serverMap当中
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值