8.2. 注册中心参考手册

Nacos

Nacos 是 Dubbo 生态系统中重要的注册中心实现,其中 dubbo-registry-nacos 则是 Dubbo 融合 Nacos 注册中心的实现。

预备工作

当您将 dubbo-registry-nacos 整合到您的 Dubbo 工程之前,请确保后台已经启动 Nacos 服务。如果您尚且不熟悉 Nacos 的基本使用的话,可先行参考 Nacos 快速入门。建议使用 Nacos 1.0.0 及以上的版本。

快速上手

Dubbo 融合 Nacos 成为注册中心的操作步骤非常简单,大致步骤可分为“增加 Maven 依赖”以及“配置注册中心“。

增加 Maven 依赖

首先,您需要将 dubbo-registry-nacos 的 Maven 依赖添加到您的项目 pom.xml 文件中,并且强烈地推荐您使用 Dubbo 2.6.5

<dependencies>
    ...
    <!-- Dubbo Nacos registry dependency -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo-registry-nacos</artifactId>
        <version>0.0.2</version>
    </dependency>   
    <!-- Keep latest Nacos client version -->
    <dependency>
        <groupId>com.alibaba.nacos</groupId>
        <artifactId>nacos-client</artifactId>
        <version>[0.6.1,)</version>
    </dependency>
    <!-- Dubbo dependency -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.6.5</version>
    </dependency>
    <!-- Alibaba Spring Context extension -->
    <dependency>
        <groupId>com.alibaba.spring</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>1.0.2</version>
    </dependency>
    ...
</dependencies>

当项目中添加 dubbo-registry-nacos 后,您无需显式地编程实现服务发现和注册逻辑,实际实现由该三方包提供,接下来配置 Naocs 注册中心。

配置注册中心

假设您 Dubbo 应用使用 Spring Framework 装配,将有两种配置方法可选,分别为:Dubbo Spring 外部化配置以及 Spring XML 配置文件,推荐前者。

Dubbo Spring 外部化配置

Dubbo Spring 外部化配置是由 Dubbo 2.5.8 引入的新特性,可通过 Spring Environment 属性自动地生成并绑定 Dubbo 配置 Bean,实现配置简化,并且降低微服务开发门槛。

假设您的 Nacos Server 同样运行在服务器 10.20.153.10 上,并使用默认 Nacos 服务端口 8848,您只需将 dubbo.registry.address 属性调整如下:

## 其他属性保持不变
## Nacos registry address
dubbo.registry.address = nacos://10.20.153.10:8848
...

随后,重启您的 Dubbo 应用,Dubbo 的服务提供和消费信息在 Nacos 控制台中可以显示:

dubbo-registry-nacos-1.png

如图所示,服务名前缀为 providers: 的信息为服务提供者的元信息,consumers: 则代表服务消费者的元信息。点击“详情 ”可查看服务状态详情:

image-dubbo-registry-nacos-2.png

如果您正在使用 Spring XML 配置文件装配 Dubbo 注册中心的话,请参考下一节。

Spring XML 配置文件

Dubbo Spring 外部化配置 配置类似,只需要调整 address 属性配置即可:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="dubbo-provider-xml-demo"  />
    <!-- 使用 Nacos 注册中心 -->
    <dubbo:registry address="nacos://10.20.153.10:8848" />
     ...
</beans>

重启 Dubbo 应用后,您同样也能发现服务提供方和消费方的注册元信息呈现在 Nacos 控制台中:

dubbo-registry-nacos-3.png

附加信息 : 在nacos-server@1.0.0版本后,支持客户端通过上报一些包含特定的元数据的实例到服务端来控制实例的一些行为。

例如: preserved.heart.beat.timeout : 该实例在不发送心跳后,从健康到不健康的时间。(单位:毫秒) preserved.ip.delete.timeout : 该实例在不发送心跳后,被服务端下掉该实例的时间。(单位:毫秒) preserved.heart.beat.interval : 该实例在客户端上报心跳的间隔时间。(单位:毫秒) preserved.instance.id.generator: 该实例的id生成策略,值为snowflake时,从0开始增加。 preserved.register.source : 保留键,目前未使用。

该功能将在Dubbo@2.7.10开始支持,通过在address中增加参数来进行配置. 例如: nacos://10.20.153.10:8848?preserved.heart.beat.timeout=15000&preserved.ip.delete.timeout=30000&preserved.heart.beat.interval=10000

Zookeeper

Zookeeper 是 Apache Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。

/user-guide/images/zookeeper.jpg

流程说明:

  • 服务提供者启动时: 向 /dubbo/com.foo.BarService/providers 目录下写入自己的 URL 地址
  • 服务消费者启动时: 订阅 /dubbo/com.foo.BarService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers 目录下写入自己的 URL 地址
  • 监控中心启动时: 订阅 /dubbo/com.foo.BarService 目录下的所有提供者和消费者 URL 地址。

支持以下功能:

  • 当提供者出现断电等异常停机时,注册中心能自动删除提供者信息
  • 当注册中心重启时,能自动恢复注册数据,以及订阅请求
  • 当会话过期时,能自动恢复注册数据,以及订阅请求
  • 当设置 <dubbo:registry check="false" /> 时,记录失败注册和订阅请求,后台定时重试
  • 可通过 <dubbo:registry username="admin" password="1234" /> 设置 zookeeper 登录信息
  • 可通过 <dubbo:registry group="dubbo" /> 设置 zookeeper 的根节点,不配置将使用默认的根节点。
  • 支持 * 号通配符 <dubbo:reference group="*" version="*" />,可订阅服务的所有分组和所有版本的提供者

使用

在 provider 和 consumer 中增加 zookeeper 客户端 jar 包依赖:

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.3.3</version>
</dependency>

或直接下载。Dubbo 支持 zkclient 和 curator 两种 Zookeeper 客户端实现:注意:在2.7.x的版本中已经移除了zkclient的实现,如果要使用zkclient客户端,需要自行拓展

使用 zkclient 客户端

2.2.0 版本开始缺省为 zkclient 实现,以提升 zookeeper 客户端的健壮性。zkclient 是 Datameer 开源的一个 Zookeeper 客户端实现。

  • 缺省配置:
    <dubbo:registry ... client="zkclient" />
    
  • 或:
    dubbo.registry.client=zkclient
    
  • 或:
    zookeeper://10.20.153.10:2181?client=zkclient
    
  • 需依赖或直接下载
    <dependency>
        <groupId>com.github.sgroschupf</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.1</version>
    </dependency>
    

使用 curator 客户端

2.3.0 版本开始支持可选 curator 实现。Curator 是 Netflix 开源的一个 Zookeeper 客户端实现。

  • 如果需要改为 curator 实现,请配置:
    <dubbo:registry ... client="curator" />
    
  • 或:
    dubbo.registry.client=curator
    
  • 或:
    zookeeper://10.20.153.10:2181?client=curator
    
  • 需依赖或直接下载curator-framework, curator-recipes
    <properties>
        <dubbo.version>2.7.8</dubbo.version>
        <zookeeper.version>2.12.0</zookeeper.version>
    </properties>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>${zookeeper.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>${zookeeper.version}</version>
    </dependency>
    

Zookeeper 单机配置:

  • <dubbo:registry address="zookeeper://10.20.153.10:2181" />
    
  • 或:
    <dubbo:registry protocol="zookeeper" address="10.20.153.10:2181" />
    

Zookeeper 集群配置:

  • <dubbo:registry address="zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181" />
    
  • 或:
    <dubbo:registry protocol="zookeeper" address="10.20.153.10:2181,10.20.153.11:2181,10.20.153.12:2181" />
    

同一 Zookeeper,分成多组注册中心:

<dubbo:registry id="chinaRegistry" protocol="zookeeper" address="10.20.153.10:2181" group="china" />
<dubbo:registry id="intlRegistry" protocol="zookeeper" address="10.20.153.10:2181" group="intl" />

zookeeper 安装

安装方式参见: Zookeeper安装手册,只需搭一个原生的 Zookeeper 服务器,并将 1.3. 快速开始 中 Provider 和 Consumer 里的 conf/dubbo.properties 中的 dubbo.registry.address 的值改为 zookeeper://127.0.0.1:2181 即可使用。

可靠性声明

阿里内部并没有采用 Zookeeper 做为注册中心,而是使用自己实现的基于数据库的注册中心,即:Zookeeper 注册中心并没有在阿里内部长时间运行的可靠性保障,此 Zookeeper 桥接实现只为开源版本提供,其可靠性依赖于 Zookeeper 本身的可靠性。

兼容性声明

2.0.8 最初设计的 zookeeper 存储结构不能扩充不同类型的数据,2.0.9 版本做了调整,所以不兼容,需全部改用 2.0.9 版本才行,以后的版本会保持兼容 2.0.92.2.0 版本改为基于 zkclient 实现,需增加 zkclient 的依赖包,2.3.0 版本增加了基于 curator 的实现,作为可选实现策略。

建议使用 2.3.3 以上版本的 zookeeper 注册中心客户端

Multicast

Multicast 注册中心不需要启动任何中心节点,只要广播地址一样,就可以互相发现。

/user-guide/images/multicast.jpg

  1. 提供方启动时广播自己的地址
  2. 消费方启动时广播订阅请求
  3. 提供方收到订阅请求时,单播自己的地址给订阅者,如果设置了 unicast=false,则广播给订阅者
  4. 消费方收到提供方地址时,连接该地址进行 RPC 调用。

组播受网络结构限制,只适合小规模应用或开发阶段使用。组播地址段: 224.0.0.0 - 239.255.255.255

配置

  • <dubbo:registry address="multicast://224.5.6.7:1234" />
    
  • <dubbo:registry protocol="multicast" address="224.5.6.7:1234" />
    

为了减少广播量,Dubbo 缺省使用单播发送提供者地址信息给消费者,如果一个机器上同时启了多个消费者进程,消费者需声明 unicast=false,否则只会有一个消费者能收到消息; 当服务者和消费者运行在同一台机器上,消费者同样需要声明unicast=false,否则消费者无法收到消息,导致No provider available for the service异常:

  • <dubbo:application name="demo-consumer">
        <dubbo:parameter key="unicast" value="false" />
    </dubbo:application>
    
  • <dubbo:consumer>
        <dubbo:parameter key="unicast" value="false" />
    </dubbo:consumer>
    

Redis

基于 Redis 实现的注册中心。从 2.1.0 版本开始支持。

Redis 过期数据通过心跳的方式检测脏数据,服务器时间必须同步,并且对服务器有一定压力,否则过期检测会不准确

/user-guide/images/dubbo-redis-registry.jpg

使用 Redis 的 Key/Map 结构存储数据结构:

  • 主 Key 为服务名和类型
  • Map 中的 Key 为 URL 地址
  • Map 中的 Value 为过期时间,用于判断脏数据,脏数据由监控中心删除 [^3]

使用 Redis 的 Publish/Subscribe 事件通知数据变更:

  • 通过事件的值区分事件类型:register, unregister, subscribe, unsubscribe
  • 普通消费者直接订阅指定服务提供者的 Key,只会收到指定服务的 register, unregister 事件
  • 监控中心通过 psubscribe 功能订阅 /dubbo/*,会收到所有服务的所有变更事件

调用过程:

  1. 服务提供方启动时,向 Key:/dubbo/com.foo.BarService/providers 下,添加当前提供者的地址
  2. 并向 Channel:/dubbo/com.foo.BarService/providers 发送 register 事件
  3. 服务消费方启动时,从 Channel:/dubbo/com.foo.BarService/providers 订阅 registerunregister 事件
  4. 并向 Key:/dubbo/com.foo.BarService/consumers 下,添加当前消费者的地址
  5. 服务消费方收到 registerunregister 事件后,从 Key:/dubbo/com.foo.BarService/providers 下获取提供者地址列表
  6. 服务监控中心启动时,从 Channel:/dubbo/* 订阅 registerunregister,以及 subscribeunsubsribe 事件
  7. 服务监控中心收到 registerunregister 事件后,从 Key:/dubbo/com.foo.BarService/providers 下获取提供者地址列表
  8. 服务监控中心收到 subscribeunsubsribe 事件后,从 Key:/dubbo/com.foo.BarService/consumers 下获取消费者地址列表

配置

  • <dubbo:registry address="redis://10.20.153.10:6379" />
    
  • <dubbo:registry address="redis://10.20.153.10:6379?backup=10.20.153.11:6379,10.20.153.12:6379" />
    
  • <dubbo:registry protocol="redis" address="10.20.153.10:6379" />
    
  • <dubbo:registry protocol="redis" address="10.20.153.10:6379,10.20.153.11:6379,10.20.153.12:6379" />
    

选项

  • 可通过 <dubbo:registry group="dubbo" /> 设置 Redis 中 key 的前缀,缺省为 dubbo
  • 可通过 <dubbo:registry cluster="replicate" /> 设置 Redis 集群策略,缺省为 failover
    • failover: 只写入和读取任意一台,失败时重试另一台,需要服务器端自行配置数据同步
    • replicate: 在客户端同时写入所有服务器,只读取单台,服务器端不需要同步,注册中心集群增大,性能压力也会更大

可靠性声明

阿里内部并没有采用 Redis 做为注册中心,而是使用自己实现的基于数据库的注册中心,即:Redis 注册中心并没有在阿里内部长时间运行的可靠性保障,此 Redis 桥接实现只为开源版本提供,其可靠性依赖于 Redis 本身的可靠性。

安装

安装方式参见: Redis安装手册,只需搭一个原生的 Redis 服务器,并将 1.3. 快速开始 中 Provider 和 Consumer 里的 conf/dubbo.properties 中的 dubbo.registry.address 的值改为 redis://127.0.0.1:6379 即可使用。

Redis 是一个高效的 KV 存储服务器

Simple

Simple 注册中心本身就是一个普通的 Dubbo 服务,可以减少第三方依赖,使整体通讯方式一致。

配置

  • 将 Simple 注册中心暴露成 Dubbo 服务:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
        <!-- 当前应用信息配置 -->
        <dubbo:application name="simple-registry" />
        <!-- 暴露服务协议配置 -->
        <dubbo:protocol port="9090" />
        <!-- 暴露服务配置 -->
        <dubbo:service interface="org.apache.dubbo.registry.RegistryService" ref="registryService" registry="N/A" ondisconnect="disconnect" callbacks="1000">
            <dubbo:method name="subscribe"><dubbo:argument index="1" callback="true" /></dubbo:method>
            <dubbo:method name="unsubscribe"><dubbo:argument index="1" callback="false" /></dubbo:method>
        </dubbo:service>
        <!-- 简单注册中心实现,可自行扩展实现集群和状态同步 -->
        <bean id="registryService" class="org.apache.dubbo.registry.simple.SimpleRegistryService" />
    </beans>
    
  • 引用 Simple Registry 服务:
    <dubbo:registry address="127.0.0.1:9090" />
    
  • 或者:
    <dubbo:service interface="org.apache.dubbo.registry.RegistryService" group="simple" version="1.0.0" ... >
    
  • 或者:
    <dubbo:registry address="127.0.0.1:9090" group="simple" version="1.0.0" />
    

适用性说明

SimpleRegistryService 只是简单实现,不支持集群,可作为自定义注册中心的参考,但不适合直接用于生产环境。

下一节:RPC 协议扩展,封装远程调用细节。