网格路由规则

Dubbo 支持 Mesh 路由类型和协作方式

基本思路

基于路由链,采用 Pipeline 处理方式,如下图所示

route-rule1.png

路由链的逻辑可以简单理解为 target = rn(…r3(r2(r1(src)))). 对于每个路由的内部逻辑,可以抽象为 n 个不相交的地址池 addrs-pool-1 … addrs-pool- n 根据实现定义的规则,取交集作为输出 addrs-out. 类推,完成整个路由链的计算.

route-rule2.png

另一方面,如果 router(n) 需要执行回退逻辑,那么回退逻辑应该在 router(n) 之后确定

回退处理原则

经过多个路由之间多个条件组件后,很容易导致筛选后的地址为空,所以我们需要针对这种情况进行回退处理,保证业务在正确的前提下能够成功找到有效地址.

首先我们看一下以下规则

apiVersion: service.dubbo.apache.org/v1alpha1
kind: VirtualService
metadata:
  name: demo-route
spec:
  hosts:
  - demo // Uniformly defined as the application name
  dubbo:
  - service:
    - exact: com.taobao.hsf.demoService:1.0.0
    - exact: com.taobao.hsf.demoService:2.0.0
    route details:
    - name: sayHello-String-method-route
      match:
      -method:
          name_match:
            exact: "sayHello"
            .....
          argp:
          - string
      route:
      -destination:
          host: demo
          subset: v1
        fallback:
          destination:
            host: demo
            subset: v2
          fallback:
            destination:
              host: demo
              subset: v3

      - name: sayHello-method-route
        match:
        -method:
            name_match:
              exact: "s-method"
        route:
        -destination:
            host: demo
            subset: v2
          fallback:
            destination:
              host: demo
              subset: v3

      - name: interface-route
        route:
        -destination:
          host: demo
          subset: v3

  - service:
      
      ....
---
apiVersion: service.dubbo.apache.org/v1alpha1
kind: DestinationRule
metadata:
  name: demo-route
spec:
  host: demo
  subsets:
  - name: v1
    labels:
      sigma.ali/mg: v1-host

  - name: v2
    labels:
      sigma.ali/mg: v2-host

  - name: v3
    labels:
      sigma.ali/mg:v3-host

以脚本路由为例,该脚本路由的匹配条件遵循一个原则,即匹配范围是从精确到宽泛的过程。在本例中,它是 sayHello(string) 参数 -> sayHello 方法 -> 接口级路由的匹配查找过程.

所以,如果我们满足了某个条件,但选定的子集地址为空,我们该如何进行回退处理呢?

以匹配 sayHello(string) 参数的条件为例,我们选择了 v1 子集。如果它为空,我们可以向上级查找地址,即在方法级别查找地址。具体的配置如下

       - name: sayHello-String-method-route
         match:
          -method:
             name_match:
               exact: "sayHello"
               .....
             argp:
              - string
         route:
          -destination:
              host: demo
              subset: v1
            fallback:
              destination:
                host: demo
                subset: v2
              fallback:
                destination:
                  host: demo
                  subset: v3

此时,我们选择的地址是 v2 方法级地址。如果 v2 仍然没有地址,根据规则的定义,我们可以回退到 v3 接口级别.

假设我们有一个方法匹配,如果没有地址,我们需要直接报错,不进行回退,我们可以这样配置

apiVersion: service.dubbo.apache.org/v1alpha1
kind: VirtualService
metadata:
  name: demo-route
spec:
  hosts:
  - demo // Uniformly defined as the application name
  dubbo:
  - service:
    - exact: com.taobao.hsf.demoService:1.0.0
    - exact: com.taobao.hsf.demoService:2.0.0
    route details:
      - name: sayHello-String-method-route
        match:
        -method:
            name_match:
              exact: "sayHello"
              .....
            argp:
            - string
        route:
        -destination:
            host: demo
            subset: v1
          fallback:
            destination:
              host: demo
              subset: v2
            fallback:
              destination:
                host: demo
                subset: v3

      - name: sayHello-method-route
        match:
        -method:
            name_match:
              exact: "s-method"
        route:
        -destination:
            host: demo
            subset: v2
          fallback:
            destination:
              host: demo
              subset: v3
      - name: some-method-route
        match:
        -method:
            name_match:
              exact: "some-method"
        route:
        -destination:
            host: demo
            subset: v4
            
      - name: interface-route
        route:
        -destination:
          host: demo
          subset: v3

  - service:

      ....
---
apiVersion: service.dubbo.apache.org/v1alpha1
kind: DestinationRule
metadata:
  name: demo-route
spec:
  host: demo
  subsets:
  - name: v1
    labels:
      sigma.ali/mg: v1-host

  - name: v2
    labels:
      sigma.ali/mg: v2-host

  - name: v3
    labels:
      sigma.ali/mg:v3-host

从这个规则可以看出,当匹配 some-method 条件时,对应 v4 子集,那么当 v4 为空时,因为没有配置回退,此时会直接报错

回退处理原则总结

  • 我们应该在 VirtualService 路由中配置 Destination 的回退处理逻辑
  • 在回退子集中,如果对应的子集也配置了回退子集,也应该递归处理;回退子集之间的关系也应该从具体到宽泛
  • 编写匹配条件时,应该遵循从具体条件到宽泛条件的原则

RouteChain 的组装方式(目前未实现)

route-rule3.png

我们看到上图,在路由过程中,我们是 Pipeline 的处理方式,Pipeline 的 Router 节点按顺序存在,每个 Router 都有一个唯一的对应 VirtualService 和 **多个** 对应的 DestinationRules 用于描述.

以存储在 Nacos 上的路由规则配置为例,配置格式如下

DataId: Demo.rule.yaml
GROUP: HSF

content:

Virtual Service A
---
DestinationRule A1
---
DestinationRule A2
---
Virtual Service B
---
DestinationRule B
---
VirtualServiceC
---
DestinationRule C
---
...

VirtualService ADestinationRule A1, DestinationRule A2 构成一个 Router A, VirtualService BDestinationRule B 构成一个 Router B, 以此类推,完成整个路由链的组装.


动态路由

Groovy 脚本动态路由.

权重路由

基于用户自定义权重实现路由功能.

用例

根据实际情况制定路由规则.

蓝绿部署

在线上旧版本继续运行的前提下,直接部署新版本,然后进行测试。当新版本通过测试后,将流量切换到新版本,最后将旧版本升级到新版本.

AB 测试

在线上旧版本继续运行的前提下,直接部署新版本,然后进行测试。当新版本通过测试后,将流量切换到新版本,最后将旧版本升级到新版本.

VirtualService

入站流量规则

金丝雀

DestinationRule

目标地址规则


上次修改时间:2023 年 1 月 2 日:增强 en 文档 (#1798) (95a9f4f6c1c)