Hi!

Actually we already have a discuss about this feature in this mailing list,
see
https://lists.apache.org/thread.html/r9222f87b69bbb8cf9dce1f5e920adb6aede38f4c24bc1b0dac07b53f%40%3Cdev.apisix.apache.org%3E
for
the details.

>From my point of view, it’s better to implement the first class support of
traffic split/shift by APISIX instead of by a plugin, since the match part
is highly consistent with Route, and Route already handles the related
logics like health check, service discovery around Upstream well. On the
contrary, introducing another Plugin which references to Upstream need to
consider these problems once again.

So what about considering the way in the above mentioned link? :)

On November 1, 2020 at 12:00:47 AM, Yuelin Zheng ([email protected]) wrote:

Hi, Community,


I have implemented a plug-in related to traffic split, and I want to add
the plug-in to apisix. The following is the main information of the plugin:


1. Background


After seeing this issue about traffic split plugin #2303(
https://github.com/apache/apisix/issues/2303), I think this function is
very useful, it can effectively realize the flow control function.
Therefore, this inspired me to implement a dynamic upstream plugin.


2. Why do this
For details, please see: https://github.com/apache/apisix/issues/2303
Traffic split means that requests need to comply with certain rules in
order to reach the designated upstream or a certain node in the upstream.
Through this function, gray release, blue-green release and custom routing
are realized, which is very useful for reducing downtime in the event of a
failure.


3. Design
The dynamic upstream plug-in is mainly composed of two parts `match` and
`upstreams` to implement the rules of the plugin. `match` is the matching
rule of the plugin (the currently supported operations are: ==, ~=, ~~, >,
>=, <, <=, in , ip_in). Only after the `match` rule is passed, can the
`upstreams` rule in the plugin be reached, otherwise the default upstream
is reached. In the `upstreams` rule, `upstream` is the configuration of the
plugin upstream, and the `weight` field is the basis for traffic
segmentation between upstream services (using the roundrobin algorithm).


note:
```
{
"Weight": 1
}
```
When the plug-in upstream configuration has only the weight field, it means
the default upstream traffic ratio.


Example:


Grayscale release:
The traffic is split according to the weight field value configured in the
upstreams part of the plug-in.
If `match` is not configured, match is passed by default. Divide the
request traffic by 4:1, 4/5 of the traffic hits the upstream of the plugin
port of `1981`, and 1/5 of the traffic hits the default upstream of the
`1980` port.


```
"plugins": {
"dynamic-upstream": {
"rules": [
{
"upstreams": [
{
"upstream": {
"name": "upstream_A",
"type": "roundrobin",
"nodes": {
"127.0.0.1:1981":10
}
},
"weight": 4
},
{

"weight": 1
}

]
}
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
```


Blue-green release:
All requests hit the upstrean configured by the plugin (when weight is 0,
the corresponding upstream is invalid).


```
"plugins": {
"dynamic-upstream": {
"rules": [
{
"match": [
{
"vars": [
[ "http_new-release","==","blue" ]
]
}
],
"upstreams": [
{
"upstream": {
"name": "upstream_A",
"type": "roundrobin",
"nodes": {
"127.0.0.1:1981":10
}
},
"weight": 1
},
{

"weight": 0
}

]
}
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
```


Custom release:
There are multiple conditions in vars, and the relationship between them is
`add`. Multiple vars can be configured, then they have an `or` relationship.
After the `match` rule is passed, the traffic is divided into 4:2, 2/3 of
the traffic hits the plug-in upstream of the `1981` port, and 1/3 of the
traffic hits the default upstream of the `1980` port.


```
"plugins": {
"dynamic-upstream": {
"rules": [
{
"match": [
{
"vars": [
[ "arg_name","==","jack" ],
[ "http_user-id",">=","23" ],
[ "http_apisix-key","~~","[a-z]+" ]
]
}
],
"upstreams": [
{
"upstream": {
"name": "upstream_A",
"type": "roundrobin",
"nodes": {
"127.0.0.1:1981":10
}
},
"weight": 4
},
{

“weight”: 2

}

]
}
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
```


Note: The vars parameter here can be obtained from the http request header,
querystring or nginx variable.
The above is a brief introduction to the dynamic upstream plugin.


I want to add this plugin to the apisix project, what do you think?

Reply via email to