Send a share of requests to a new version
A new version of the orders backend is ready, and you want it to meet real clients before it takes all of them. The plugin traffic-split on orders-api sends a share of the route's requests to the new version and leaves the rest with the route's own upstream, the current version. This guide starts the new version on a tenth of the requests. You raise its share as it proves itself, until it takes them all. At the end, the new version takes one share in ten of the route's requests, and the current version the other nine.
Before you start
- This guide starts from
orders-apias Route requests to a backend leaves it, with key-auth from Require an API key. Its backend nodes are the current version. The requests below call/orders/42. A plugin from another guide that this page does not name can change the answers below; remove it first or work on a copy of the route. - The address and port of each backend node of the new version, reachable from the gateway nodes. The team that runs the backend gives you them.
- The host name of your gateway. In the console it is the first part of the Address line on a route's Overview tab,
api.example.comin this page's examples; replace it in every request below. - The Editor or Environment administrator role in this environment.
Steps
1. Create an upstream for the new version
The new version gets an upstream of its own, so its backend nodes are kept in one place. In the menu, select Upstreams, then New upstream. Under General, give it a Name that says which version it is. Under Targets, add one row for each backend node of the new version with its Host, Port and a Weight of 1. Share a backend between routes shows these fields step by step. Select Create upstream.
The upstream form has no field for the ID, so the gateway gives every upstream you create in the console its ID. Open the upstream under Upstreams and read its ID in the Metadata card of its Overview tab. Leave orders-api as it is: it keeps sending to the current version.
2. Choose traffic-split
Open orders-api under Routes, select its Plugins tab, then Add plugin at the top right of the tab. Open the Traffic category, or type traffic-split in the search box. Select traffic-split, then Configure.
3. Add one rule with two shares
Under Rules, select Add entry. Leave the rule's Match empty, so the rule takes every request. Under its Weighted upstreams, select Add entry twice and fill in the two entries.
| Entry | Upstream ID | Weight | Why |
|---|---|---|---|
| First | the new version's upstream | 1 | One share for the new version. |
| Second | leave empty | 9 | An entry that names no upstream stands for the route's own upstream, so the current version keeps nine shares. |
An entry offers two ways to name its upstream. Upstream ID picks an existing upstream by its ID, the one you created in step 1. Upstream is an upstream written inline here for this share alone, with nodes of its own.
In the first entry, type the upstream's name or ID into Upstream ID and pick it from the list. Leave Upstream empty in both entries.
Select Add plugin at the bottom of the panel. The plugin is saved like this:
{
"rules": [
{
"weighted_upstreams": [
{
"upstream_id": "checkout-v2",
"weight": 1
},
{
"weight": 9
}
]
}
]
}
The saved object names the upstream by its ID, checkout-v2 in this example; yours shows the ID of the upstream you created. The example's upstream was written through the API, which can set an ID of its own choosing.
From now on, the new version takes one share in ten of the route's requests, and the current version the other nine.
Check it
One request cannot show the split, because each request goes to one version or the other. Send it many times instead, and both backends answer some of the requests. key-auth is on the route, so every request carries the key of mobile-app in the x-api-key header. A shell loop sends it 100 times:
for i in $(seq 100); do curl -s -o /dev/null -w '%{http_code}\n' -H 'x-api-key: <the key of mobile-app>' 'https://<gateway host>/orders/42'; done
The single request, with its headers, is below. Add the same x-api-key header to it.
curl -i -L 'https://<gateway host>/orders/42'
- Over many requests
- Over many requests every answer is
200, and both the route's own backend and the new version answer some of them; one request on its own cannot show the split.
Raise the share
On the route's Plugins tab, select traffic-split in the list of plugins, then Edit. Change the two Weight values and select Save plugin at the bottom of the panel. The weights are shares of the rule's traffic. With 1 and 1 each version takes half, and with 20 beside 80 the new version takes a fifth.
To send every request to the new version, set the second entry's weight to 0. A weight of 0 takes an entry out of the split. It does so only while another entry of the same rule carries a weight above 0. To send every request back to the current version, set the first entry's weight to 0 instead.
Once the new version serves every request well, point orders-api at its upstream, as the last step of Share a backend between routes shows. Then, on the route's Plugins tab, open the actions menu at the right of the traffic-split row and select Remove. Confirm with Remove plugin.
What to know
- The rules are read in order, and the first rule whose conditions pass takes the request. A rule without conditions takes every request and hides every rule below it. A request no rule takes goes to the route's own upstream.
- To send only some clients to the new version, give the rule a Match. The rule then takes a request when any one of its condition sets passes.
- An upstream ID that names no upstream is stored, and then every request of the rule fails. Pick the upstream from the list rather than typing an ID.
- A rule holds at most 20 entries. More are refused when you save.
Related
- Route requests to a backend: the route whose requests this guide splits.
- Share a backend between routes: an upstream with a health check, and pointing a route at it.
- traffic-split and Upstream in the reference.