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?
