基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

Dubbo的服务路由规则

知识点图片

Dubbo服务路由通过条件/标签规则,在负载均衡前筛选提供者,实现灰度发布、环境隔离等流量治理。

我们来详细解析一下 Dubbo 的服务路由规则。

服务路由(Service Routing)是 Dubbo 流量治理的核心功能之一。它的主要目的是在服务消费者(Consumer)发起调用时,从注册中心返回的所有服务提供者(Provider)地址列表中,根据预设的规则筛选出一部分符合条件的 Provider,然后再由负载均衡策略从这个子集中选择一个最终的 Provider 进行调用

简单来说,路由规则决定了“哪些消费者可以调用哪些提供者”。


一、为什么需要服务路由?

服务路由解决了微服务架构中的许多关键问题,主要应用场景包括:

  1. 灰度发布 (Grayscale Release):当新版本服务上线时,可以先让一小部分流量(例如来自特定 IP、特定用户或内部员工的请求)访问新版本的 Provider,验证其稳定性,然后逐步扩大流量范围,最终实现全量上线。
  2. 多环境/多机房隔离 (Multi-environment/Data Center Isolation):在开发、测试、预发、生产等多个环境中,确保消费者的调用只发生在当前环境内,避免跨环境调用导致数据污染或服务异常。同理,可以实现同机房优先调用,减少网络延迟。
  3. 流量切换与容灾 (Traffic Shifting & Disaster Recovery):当某个机房或服务集群出现故障时,可以快速通过路由规则将流量切换到正常的机房或集群,实现服务容灾。
  4. 读写分离 (Read/Write Separation):对于某些服务,可以将写请求路由到主节点,读请求路由到从节点,实现读写分离。
  5. 为重要应用预留资源:将某些核心服务的 Provider 实例专门留给核心的 Consumer 应用调用,避免被非核心应用占用资源。

二、Dubbo 路由规则的分类(以 Dubbo 3.x 为例)

Dubbo 3.x 推荐使用基于 YAML 格式的路由规则,通过动态配置中心(如 Nacos, Zookeeper, Apollo)下发。主要分为以下两种:

1. 条件路由 (Conditional Routing)

这是最常用、最灵活的路由方式。它允许你根据调用上下文中的参数(如方法名、参数值、attachments)或者 Provider 的 URL 属性(如 IP 地址、端口、应用名)来定义路由规则。

核心要素:

  • scope: 规则的作用范围,可以是 service(服务级别)或 application(应用级别)。
  • key: 规则的唯一标识,通常是服务名或应用名。
  • conditions: 路由规则的核心,定义了匹配条件。它是一个 when => then 格式的表达式。
    • when: 消费者匹配条件。如果消费者的上下文信息满足 when 条件,则此规则对其生效。
    • then: 提供者匹配条件。消费者会从满足 then 条件的提供者列表中选择。
  • force: 是否强制执行。true 表示如果筛选后没有可用的 Provider,则直接报错;false 表示如果筛选后没有可用 Provider,则忽略此规则,使用所有 Provider。默认为 true

示例:灰度发布

假设有一个 com.example.UserService 服务,新版本 2.0.0 已经部署在一台机器 192.168.1.100 上。我们希望所有来自应用 frontend-app 的调用,都路由到这台新版本的机器上。

yaml
# 存储在配置中心:/dubbo/config/com.example.UserService/dubbo.routing.yml
scope: service
key: com.example.UserService
force: true
conditions:
  # 规则1:来自 frontend-app 的消费者,只能调用 IP 为 192.168.1.100 的提供者
  - when:
      - consumer.application=frontend-app
    then:
      - provider.host=192.168.1.100

示例:同机房优先

假设有两个机房 hzsh。我们希望来自 hz 机房的消费者优先调用 hz 机房的提供者。

yaml
# 存储在配置中心:/dubbo/config/dubbo/dubbo.routing.yml (应用级规则)
scope: application
key: my-consumer-app
force: false  # force=false 很重要,如果同机房没有,可以跨机房调用
conditions:
  # 规则1:如果消费者在 hz 机房,则优先调用 hz 机房的提供者
  - when:
      - consumer.meta[zone]=hz
    then:
      - provider.meta[zone]=hz
  # 规则2:如果消费者在 sh 机房,则优先调用 sh 机房的提供者
  - when:
      - consumer.meta[zone]=sh
    then:
      - provider.meta[zone]=sh

这里的 meta 是 Dubbo 3 的元数据中心信息,也可以通过 provider/consumer 的其他属性来标识机房。

2. 标签路由 (Tag Routing)

标签路由是条件路由的一种简化和特例,专门用于灰度发布、蓝绿部署等场景。它通过给 Provider 打上不同的“标签”(如 gray, stable),消费者在调用时指定需要访问的标签,从而实现流量的精细化控制。

核心要素:

  • Provider 启动时通过配置声明自己的标签。
  • Consumer 在调用时通过 RpcContext 动态指定要请求的标签。
  • 也可以通过路由规则为某类 Consumer 静态地绑定到某个标签的 Provider。

配置方式:

第一步:Provider 端配置标签

plaintext
# application.properties
dubbo.provider.tag=gray

第二步:Consumer 端调用

方式A:动态标签路由(推荐)
消费者在代码中动态指定本次调用要访问的标签。

java
// 本次调用将只会发送到标签为 "gray" 的 Provider
RpcContext.getContext().setAttachment("dubbo.tag", "gray");
userService.sayHello("world");

方式B:静态标签路由(通过规则配置)
为某个应用或 IP 的所有调用都路由到带特定标签的 Provider。

yaml
# 存储在配置中心:/dubbo/config/com.example.UserService/dubbo.tag-router.yml
scope: service
key: com.example.UserService
force: true
tags:
  # 规则1: 将来自 10.0.0.1 的消费者的请求,路由到标签为 gray 的提供者
  - name: gray
    addresses: ["10.0.0.1"]
  # 规则2: 其他所有请求,都路由到没有标签的提供者
  - name: default
    addresses: ["0.0.0.0/0"] # 匹配所有

三、路由规则的执行流程

  1. 获取 Provider 列表:Consumer 从注册中心获取所有可用的 Provider 地址列表。
  2. 执行路由规则链:Dubbo 会依次执行所有适用的路由规则(条件路由、标签路由等),对 Provider 列表进行层层过滤
  3. AND 逻辑:一个 Provider 必须同时满足所有路由规则的条件,才能保留在最终的候选列表中。
  4. 负载均衡:路由规则执行完毕后,得到一个符合条件的 Provider 子集。
  5. 最终选择:负载均衡策略(如 Random, RoundRobin)从这个子集中选择一个 Provider 发起最终调用。

关键点:路由(Routing)发生在负载均衡(Load Balance)之前。 路由是筛选,负载均衡是选择。


四、Dubbo 2.7 与 3.x 的差异

  • 配置格式

    • Dubbo 2.7:主要使用基于 URL 的格式,通过 Dubbo Admin 或直接写入 Zookeeper /dubbo/服务名/routers 节点。格式比较晦涩难懂,例如 host = 10.20.153.10 => host = 10.20.153.11。还支持脚本路由(如 JavaScript),灵活性高但有性能和安全风险。
    • Dubbo 3.x:全面拥抱云原生,推荐使用标准化的 YAML 格式。语义更清晰,结构化更好,更易于维护和理解。
  • 概念

    • 核心思想(条件、标签)是类似的,但 3.x 的实现更加标准化和强大。
    • 3.x 引入了 scope (service/application) 的概念,使得规则管理更加灵活。

总结

Dubbo 的服务路由规则是实现精细化流量治理的强大武器。

  • 条件路由是最基础和灵活的规则,适用于各种复杂的场景。
  • 标签路由是针对灰度发布等场景的简化版,使用起来更方便。
  • 路由规则的核心作用是在负载均衡前对 Provider 列表进行过滤
  • 在 Dubbo 3.x 中,推荐使用 YAML 格式通过动态配置中心来管理路由规则,这已经成为现代微服务治理的最佳实践。
00:00
00:00