动态路由
Groovy 脚本动态路由.
基于路由链,采用 Pipeline 处理方式,如下图所示
路由链的逻辑可以简单理解为 target = rn(…r3(r2(r1(src)))). 对于每个路由的内部逻辑,可以抽象为 n 个不相交的地址池 addrs-pool-1 … addrs-pool- n 根据实现定义的规则,取交集作为输出 addrs-out. 类推,完成整个路由链的计算.
另一方面,如果 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 为空时,因为没有配置回退,此时会直接报错
我们看到上图,在路由过程中,我们是 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 A
和 DestinationRule A1
, DestinationRule A2
构成一个 Router A, VirtualService B
和 DestinationRule B
构成一个 Router B, 以此类推,完成整个路由链的组装.
Groovy 脚本动态路由.
基于用户自定义权重实现路由功能.
根据实际情况制定路由规则.
在线上旧版本继续运行的前提下,直接部署新版本,然后进行测试。当新版本通过测试后,将流量切换到新版本,最后将旧版本升级到新版本.
在线上旧版本继续运行的前提下,直接部署新版本,然后进行测试。当新版本通过测试后,将流量切换到新版本,最后将旧版本升级到新版本.
入站流量规则
目标地址规则