整合服务发现
1. Dubbo服务发现机制
Dubbo依赖第三方注册中心组件来协调服务发现过程, 支持常用的注册中心如Nacos、Consul、Zookeeper等。
服务发现包含提供者、消费者和注册中心三个参与角色,其中Dubbo提供者实例注册URL地址到注册中心,注册中心负责对数据进行聚合,Dubbo消费者从注册中心读取地址列表并订阅变更,每当地址列表发生变化,注册中心将最新的列表通知到所有订阅的消费者实例。
2. Dubbo服务发现流程
- 首先Provider实例将自身的应用名、实例ip:port地址信息 (通常还包含少量的实例元数据,如机器所在区域、环境等) 注册到注册中心。
- 注册中心收到这些地址数据后,按照service服务名划分地址数据后进行聚合,Dubbo3地址数据存储结构如下所示:

- 每个消费服务的实例从注册中心订阅实例地址列表,按需订阅部分地址列表,比如一个消费者应用依赖app1、app2,则只会订阅app1、app2的地址列表更新,大幅减轻了冗余数据推送和解析的负担。之后消费者根据从注册中心拿到的地址信息,与提供者建立连接并通过元数据服务读取到对端的元数据配置信息,消费端将这两部分信息共同组装成地址服务列表并缓存起来。需要注意的是消费者这两个步骤都是在实际的RPC服务调用发生之前。
Dubbo2注册中心的存储数据优化
注册中心存储的数据结构如下所示:
可见聚合的数据粒度是服务级别,其次注册中心同步的数据不止包含地址,还包含了各种元数据以及配置。好处就是方便服务治理。但是出现两点突出问题:
- 首先,注册中心集群容量达到上限阈值。由于所有的URL地址数据都被发送到注册中心,注册中心的存储容量达到上限,推送效率也随之下降。
- 而在消费端这一侧,Dubbo2框架常驻内存已超40%,每次地址推送带来的cpu等资源消耗率也非常高,影响正常的业务调用。
Dubbo3将注册中心数据存储简化,只存了地址和端口信息,元数据部分被精简掉了。又为了延续Dubbo2的精细化服务治理能力,Dubbo3引入一个内置的MetadataService元数据服务,由中心化推送转为Consumer到Provider的点对点拉取。
3. 使用Zookeeper作为注册中心
3.1 添加依赖
<!-- 推荐Zookeeper Server3.8.0+版本 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-zookeeper-curator5-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!-- 仅当Zookeeper Server版本是3.4.x及以下时,使用此依赖
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-zookeeper-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
-->3.2 配置启用Zookeeper
# application.yml
dubbo
registry
# 也可以不带协议开头,10.20.153.10:2181,10.20.153.11:2181,10.20.153.12:2181
address: zookeeper://localhost:2181
# 如果Zookeeper开启认证
# username: hello
# password: 1234
# 配置连接、会话过期时间
timeout: 30 * 1000* # 连接超时时间,默认 30s
session: 60 * 1000* # 会话超时时间,默认 60s
group: /ep # 指定zk根节点3.3 服务注册细节
ZK存储结构如下:
流程如下:
服务提供者启动时: 向/dubbo/com.foo.BarService/providers目录下写入自己的URL地址。
服务消费者启动时: 订阅/dubbo/com.foo.BarService/providers目录下的提供者URL地址。并向/dubbo/com.foo.BarService/consumers目录下写入自己的URL地址。
监控中心启动时: 订阅/dubbo/com.foo.BarService目录下的所有提供者和消费者URL地址。
3.4 应用级节点结构
应用级服务发现的地址结构比接口级更精简,它以应用名为粒度分发地址列表。服务提供者启动时,向 /services/app 目录下写入自己的URL地址 在应用级服务发现中,zookeeper注册中心还会存储一份额外的元数据,用于解决接口名到应用名之间的映射关系,其存储结构如下:
service1节点的value值是应用列表,可通过get/dubbo/mapping/service1查看:app1,app2
另外默认是点对点的元数据模式,可通过dubbo.registry.metadata-type=remote开启集中式元数据模式, ZK节点还会增加如下内容:
4. 使用Nacos作为注册中心
4.1 增加依赖
Nacos版本映射关系:
| Dubbo | 推荐Nacos版本 | Nacos兼容范围 |
|---|---|---|
| 3.3.0 | 2.3.0 | 2.x |
| 3.2.21 | 2.1.0 | 2.x |
| 3.1.11 | 2.0.9 | 2.x |
| 3.0.10 | 2.0.9 | 2.x |
| 2.7.21 | 1.x最新版本 | 1.x |
| 2.6.0 | 1.x最新版本 | 1.x |
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-nacos-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>4.2 配置启用Nacos
# application.yml (Spring Boot)
dubbo
registry
address: nacos://localhost:8848
## 认证
address: nacos://localhost:8848?username=nacos&password=nacos
## 自定义命名空间
address: nacos://localhost:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932
# group不配置是由Nacos指定默认分组
# group: dubbo启动Dubbo应用,Dubbo的服务提供者在Nacos控制台中可以显示:
如果想要在Nacos页面中也显示服务消费者,可以加上?register-consumer-url=true参数。
4.3 Nacos注册数据结构
Dubbo3对于服务提供者默认采用"应用级服务发现+接口级服务发现"的双注册模式,因此会发现应用级服务(应用名)和接口级服务(接口名)同时出现在Nacos控制台,可以通过配置dubbo.registry.register-mode=instance/interface/all来改变注册行为。 
