Dubbo 源码分析 – 服务导出

1.服务导出过程

本篇文章,我们来研究一下 Dubbo 导出服务的过程。Dubbo 服务导出过程始于 Spring 容器发布刷新事件,Dubbo 在接收到事件后,会立即执行服务导出逻辑。整个逻辑大致可分为三个部分,第一是前置工作,主要用于检查参数,组装 URL。第二是导出服务,包含导出服务到本地 (JVM),和导出服务到远程两个过程。第三是向注册中心注册服务,用于服务发现。本篇文章将会对这三个部分代码进行详细的分析,在分析之前,我们先来了解一下服务的导出过程。

Dubbo 支持两种服务导出方式,分别延迟导出和立即导出。延迟导出的入口是 ServiceBean 的 afterPropertiesSet 方法,立即导出的入口是 ServiceBean 的 onApplicationEvent 方法。本文打算分析服务延迟导出过程,因此不会分析 afterPropertiesSet 方法。下面从 onApplicationEvent 方法说起,该方法收到 Spring 容器的刷新事件后,会调用 export 方法执行服务导出操作。服务导出之前,要进行对一系列的配置进行检查,以及生成 URL。准备工作做完,随后开始导出服务。首先导出到本地,然后再导出到远程。导出到本地就是将服务导出到 JVM 中,此过程比较简单。导出到远程的过程则要复杂的多,以 dubbo 协议为例,DubboProtocol 类的 export 方法将会被调用。该方法主要用于创建 Exporter 和 ExchangeServer。ExchangeServer 本身并不具备通信能力,需要借助更底层的 Server 实现通信功能。因此,在创建 ExchangeServer 实例时,需要先创建 NettyServer 或者 MinaServer 实例,并将实例作为参数传给 ExchangeServer 实现类的构造方法。ExchangeServer 实例创建完成后,导出服务到远程的过程也就接近尾声了。服务导出结束后,服务消费者即可通过直联的方式消费服务。当然,一般我们不会使用直联的方式消费服务。所以,在服务导出结束后,紧接着要做的事情是向注册中心注册服务。此时,客户端即可从注册中心发现服务。

以上就是 Dubbo 服务导出的过程,比较复杂。下面开始分析源码,从源码的角度展现整个过程。

2.源码分析

一场 Dubbo 源码分析的马拉松比赛即将开始,现在我们站在赛道的起点进行热身准备。本次比赛的起点位置位于 ServiceBean 的 onApplicationEvent 方法处。好了,发令枪响了,我将和一些朋友从 onApplicationEvent 方法处出发,探索 Dubbo 服务导出的全过程。下面我们来看一下 onApplicationEvent 方法的源码。

public void onApplicationEvent(ContextRefreshedEvent event) {
    // 是否有延迟导出 && 是否已导出 && 是不是已被取消导出
    if (isDelay() && !isExported() && !isUnexported()) {
        // 导出服务
        export();
    }
}

onApplicationEvent 是一个事件响应方法,该方法会在收到 Spring 上下文刷新事件后执行。这个方法首先会根据条件决定是否导出服务,比如有些服务设置了延时导出,那么此时就不应该在此处导出。还有一些服务已经被导出了,或者当前服务被取消导出了,此时也不能再次导出相关服务。注意这里的 isDelay 方法,这个方法字面意思是“是否延迟导出服务”,返回 true 表示延迟导出,false 表示不延迟导出。但是该方法真实意思却并非如此,当方法返回 true 时,表示无需延迟导出。返回 false 时,表示需要延迟导出。与字面意思恰恰相反,让人觉得很奇怪。下面我们来看一下这个方法的逻辑。

// -☆- ServiceBean
private boolean isDelay() {
    // 获取 delay
    Integer delay = getDelay();
    ProviderConfig provider = getProvider();
    if (delay == null && provider != null) {
        // 如果前面获取的 delay 为空,这里继续获取
        delay = provider.getDelay();
    }
    // 判断 delay 是否为空,或者等于 -1
    return supportedApplicationListener && (delay == null || delay == -1);
}

暂时忽略 supportedApplicationListener 这个条件,当 delay 为空,或者等于-1时,该方法返回 true

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值