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