動態路由
基於 Groovy 腳本的動態路由。
基於路由鏈,採用 Pipeline 處理方式,如下圖所示
路由鏈的邏輯可以簡單理解為 target = rn(…r3(r2(r1(src)))). 對於每個路由器的內部邏輯,可以抽象為 n 個不相交的地址池 addrs-pool-1 … addrs-pool-n,根據實現定義的規則取交集作為輸出 addrs-out。以此類推,完成整個路由鏈的計算。
另一方面,如果 router(n) 需要執行 fallback 邏輯,則 fallback 邏輯應該在 router(n) 之後確定
經過多個路由器之間的多個條件元件後,很容易將地址過濾為空,因此需要針對這種情況進行 fallback 處理,以保證業務在正確的前提下能順利找到有效的地址。
首先我們看以下規則
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 方法 -> 接口級路由的匹配查找過程。
那麼如果我們滿足了某個條件,但選出的子集地址為空,我們將如何進行 fallback 處理?
以匹配 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 仍然沒有地址,根據規則的定義,我們可以 fallback 到 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 為空時,由於沒有配置 fallback,此時會直接報錯
我們看到上圖,在路由過程中,我們是 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 腳本的動態路由。
基於使用者自定義權重的路由功能實現。
根據實際情況制定路由規則。
在線上舊版本繼續執行的前提下,直接部署新版本然後進行測試。當新版本通過測試後,將流量切換到新版本,最後將舊版本升級到新版本。
在線上舊版本繼續執行的前提下,直接部署新版本然後進行測試。當新版本通過測試後,將流量切換到新版本,最後將舊版本升級到新版本。
入站流量規則
目標地址規則