Dubbo 服务注册与发现
前言
大家好,今天开始给大家分享 — Dubbo 专题之 Dubbo 服务注册与发现:在上个章节中我们简单的介绍了 Dubbo 中的四大角色,其中服务注册和服务发现就涉及到我们把一个本地服务暴露给远程客户端调用和本地客户端引用一个远程服务的过程。那么我们现在就开始吧!
1. 什么是服务注册
根据上个章节的讨论,我们可以知道服务提供者和服务消费者都会向注册中心注册服务相关的元信息(具体元信息请查阅上个章节)。当我们需要暴露一个服务给其他应用端调用时那么应用端是怎样知道我们的服务在哪里?暴露了什么接口?通讯端口是多少?这些信息客户端是怎样获取的呢?这些都需要我们的服务提供者向我们的注册中心注册,消费端获取这些注册元信息再进行远程调用。那么服务提供者向注册中心注册元信息的过程就是服务注册。整个服务注册过程大致包括了:参数检测,URL 组装、本地服务导出,远程服务导出、注册中心服务注册。
2. 什么是服务引用
在 Dubbo 中服务引用发生在两种情况分别是:Spring 容器回调生命周期方法 afterPropertiesSet 和服务被注入到其他类引用的时候。很明显第一种是只要 Spring 容器启动都会去回调所有 afterPropertiesSet 方法进行回调属于一种饿汉式方式(一上来就开干),而另外一种则是在我们注入使用的时候属于懒汉式方式(使用的时候才发生关系)。两种方式各有优缺点:饿汉式可以在应用容器启动时候进行合法性检测,而懒汉式在使用时加载提高了应用启动速度但是也带来了一些只有在使用时才能发现的问题。
Tips:我上面说的是 Dubbo 2.6.x 及以前版本,在 Dubbo 2.7.x 中只存在第二种。那么服务的引用简单来说就是获取对远程服务调用的代理对象。
3. Dubbo 中的服务注册与发现流程
服务注册流程
当我们的 Spring 容器启动完成的时候会发布 ContextRefreshedEvent 事件,那么 Dubbo 通过DubboBootstrapApplicationListener 监听类来接收 ContextRefreshedEvent 事件。
Tips:这是 Dubbo 与 Spring 整合的切入点。
当监听器接收到 ContextRefreshedEvent 事件后,Dubbo 会做以下几点事情:暴露服务、导出元数据、注册本地服务实例、初始化远程调用代理对象。导出元数据(在 Dubbo2.7.x 中元数据和配置信息是分离的这里仅仅导出的是元数据)、注册本地实例(在 JVM 导出服务)、初始化远程代理对象(其实就是创建一个调用远程的 Invoker 代理对象)。
其中这里我们主要讨论暴露服务,那么暴露服务过程主要做了以下几部分事情。第一部分是前置工作:主要用于检查参数,组装 URL。第二部分是导出服务:包含导出服务到本地 (JVM)和导出服务到远程两个过程。第三部分是向注册中心注册服务:用于服务发现。
服务发现流程
首先我们的 ReferenceBean 是实现 FactoryBean 接口,属性 Spring 的小伙伴都知道当我们通过 Spring 容器进行依赖注入或者是依赖查找 bean 时会触发 getObject 方法被调用,而 ReferenceBean 重新改写该方法,因此
ReferenceBean#getObject
会被在从 Spring 容器中获取 bean 时触发回调。Tips:这是整个服务引用的切入点。
getObject 重载方法被调用,首先会检查配置属性、参数校验等。
check 本地存根、mock 检查。(后面章节会详细介绍)
创建远程代理对象。
以上的流程分析大家可以根据我对 Dubbo 2.7.x 源码的注释一起学习,代码的分析入口类DubboBootstrapApplicationListener#onApplicationContextEvent
。
代码地址:https://github.com/liyong1028826685/dubbo.git
Tips:代码是基于2.7.x版本。
4. 小结
在本小节中我们主要学习了 Dubbo 中的服务注册和服务引用的概念,并深入的学习了服务注册和服务引用的主要流程以及和 Spring 整合的两个切入点:DubboBootstrapApplicationListener#onApplicationContextEvent
、ReferenceBean#getObject
,同时也注意到了 Dubbo 2.6.x 和 Dubbo 2.7.x 版本的一些差异。
本节课程的重点如下:
理解 Dubbo 中服务注册
理解 Dubbo 中服务引用
了解 Dubbo 中服务注册流程
了解 Dubbo 中服务注册引用
了解 Dubbo 与 Spring 整合的切入点