Dubbo Mesh routing rules are based on Istio’s VirtualService and DestinationRule modifications. The overall idea and format can refer to Istio’s traffic control rules reference manual: Istio VirtualService and Istio DestinationRule
This article describes the design principles of Dubbo Mesh routing rules, as well as the differences between them and Istio rules. Reference link: https://www.yuque.com/docs/share/c132d5db-0dcb-487f-8833-7c7732964bd4?#.
Based on the routing chain, the Pipeline processing method is adopted, as shown in the figure below:
The logic of the routing chain can be simply understood as target = rn(…r3(r2(r1(src)))). For the internal logic of each router, it can be abstracted as the input address addrs-in and the n mutually exclusive address pools addrs-pool-1 … addrs-pool-n that are split according to the full address addrs-all in the router. The intersection is taken as the output addrs-out according to the rules defined by the implementation. By analogy, the calculation of the entire routing chain is completed.
On the other hand, if router(n) needs to execute fallback logic, then after passing through router(n), the fallback logic should be determined.
Due to multiple conditional components between multiple routers, it is easy for the address to be filtered out. In this case, we need to perform fallback handling to ensure that the business can smoothly find a valid address under the premise of correctness.
First, let’s look at the following rule
apiVersion: service.dubbo.apache.org/v1alpha1
kind: VirtualService
metadata:
name: demo-route
spec:
hosts:
- demo
dubbo:
- service:
- exact: com.taobao.hsf.demoService:1.0.0
- exact: com.taobao.hsf.demoService:2.0.0
routedetail:
- 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
Taking script routing as an example, the matching condition of this script routing follows a principle, which is that the matching range is a process from precise to broad. In this example, it is a matching search process from the sayHello(string) parameter -> sayHello method -> interface-level routing.
So if we have met a certain condition but the selected subset address is empty, how do we perform fallback handling?
Taking the matching sayHello(string) parameter condition as an example, we select the v1 subset. If it is empty, we can look for the address at the next level, which is to look for the address at the method level. The specific configuration is as follows
- 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
At this time, the address we selected is the v2 method-level address. If v2 still has no address, according to the definition of the rule, we can fallback to the v3 interface level.
Suppose we have a method match, if there is no address, we need not to perform fallback and directly report an error. We can configure it like this
apiVersion: service.dubbo.apache.org/v1alpha1
kind: VirtualService
metadata:
name: demo-route
spec:
hosts:
- demo
dubbo:
- service:
- exact: com.taobao.hsf.demoService:1.0.0
- exact: com.taobao.hsf.demoService:2.0.0
routedetail:
- 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
From this rule, we can see that when matching the some-method condition, the corresponding v4 subset is selected. When v4 is empty, because there is no fallback configured, an error will be reported directly.
As we can see in the above figure, in the routing process, we use the Pipeline processing method. The Router nodes in the Pipeline are sequential, and each Router has a unique corresponding VirtualService and multiple corresponding DestinationRules for description.
Taking the routing rule configuration stored in Nacos as an example, the configuration format is as follows:
DataId: Demo.rule.yaml
GROUP: HSF
content:
VirtualService A
---
DestinationRule A1
---
DestinationRule A2
---
VirtualService B
---
DestinationRule B
---
VirtualService C
---
DestinationRule C
---
...
VirtualService A
and DestinationRule A1
, DestinationRule A2
form a Router A, VirtualService B
and DestinationRule B
form Router B, and so on, completing the assembly of the entire router chain.
Note, although the following rules are very similar to Istio’s VirtualService and DestinationRule, there are some differences in the working process and specific rules compared to Istio. Dubbo only references Istio’s design. If you want to integrate with the native Istio service mesh governance system, please refer to Integrating Service Mesh Traffic Governance.
In some scenarios, we need to distribute traffic with the same attributes proportionally to different instance groups. A typical example scenario is A/B testing, where we need to forward 20% of the traffic to the new version v2 of the service to verify the stability of the new version, or to direct a portion of internal company users to the new version v2 for testing and verification. Another application scenario is to achieve canary releases of services, gradually adjusting the traffic distribution ratio so that the new version’s traffic gradually increases and eventually fully migrates all traffic to the new version.
The following example will proportionally forward all requests to the getDetail
method of the service org.apache.dubbo.demo.DetailService
.
...
apiVersion: service.dubbo.apache.org/v1alpha1
kind: VirtualService
metadata:
name: details
spec:
dubbo:
- name: detail-service-traffic-split
match:
- name:
services:
- exact: "org.apache.dubbo.demo.DetailService"
method:
name_match:
exact: "getDetail"
route:
- destination:
subset: details-v1
weight: 60
- destination:
subset: details-v2
weight: 40
---
...
apiVersion: service.dubbo.apache.org/v1alpha1
kind: DestinationRule
metadata:
name: reviews-route
spec:
subsets:
- name: details-v1
labels:
detail_version: v1 # 'version' is a reserved key in Dubbo, so must not be used.
- name: details-v2
labels:
detail_version: v2 # 'version' is a reserved key in Dubbo, so must not be used.
---
This part can fully refer to the semantics of Istio VirtualService, as they are almost identical. Dubbo adds the
dubbo
protocol label (corresponding to the http protocol position) and enriches thematch
conditions.
The match
condition sets the traffic rule to be effective only for requests to the getDetail
method of the service “org.apache.dubbo.demo.DetailService”.
match:
- name:
services:
- exact: "org.apache.dubbo.demo.DetailService"
method:
name_match:
exact: "getDetail"
The following route
specifies the target instance subsets for the matched traffic. The instance subsets details-v1
and details-v2
are defined through the DestinationRule below. For unmatched traffic, it can access any instance by default without any filtering.
route:
- destination:
subset: details-v1
weight: 60
- destination:
subset: details-v2
weight: 40
This part can fully refer to the semantics of Istio DestinationRule, as they are identical.
The following rule divides the application details into two deployment versions v1
and v2
by matching the detail_version
value, named details-v1
and details-v2
respectively. At the same time, details-v1
and details-v2
will become the traffic forwarding target objects of Dubbo VirtualService.
subsets:
- name: details-v1
labels:
detail_version: v1 # 'version' is a reserved key in Dubbo, so must not be used.
- name: details-v2
labels:
detail_version: v2 # 'version' is a reserved key in Dubbo, so must not be used.
Similar to label routing, this involves how to label your instances (here it is
detail_version
). Please refer to the section How to Label Instances below.
In addition to the functions introduced above that are very similar to Istio’s traffic rules, Dubbo’s VirtualService and DestinationRule can also achieve things that Istio rules cannot, such as method parameter routing. For details, see the Reference Manual.