Skip to main content

Version: 3.9.0

Manage Traffic Conditionally

Conditional traffic management refers to the ability to execute specific actions based on certain characteristics of each request, such as request headers, URI parameters, or URI paths. This enables one to implement dynamic and flexible routing, rate limiting, or other actions, allowing for granular control and customization of the gateway's behavior based on the specific needs of the application or system.

This guide will show you how you can manage traffic conditionally in APISIX using the traffic-split, traffic-label, and workflow plugins.

Prerequisite(s)

Forward Traffic Conditionally and Proportionally

In this section, you will learn how to forward traffic to different upstream services conditionally and by weights, using the traffic-split plugin.

Create a route as such:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"uri": "/headers",
"id": "traffic-split-route",
"plugins": {
"traffic-split": {
"rules": [
{
"match": [
{
"vars": [
["arg_name","==","jack"],
["http_user-id",">","23"],
["http_apisix-key","~~","[a-z]+"]
]
}
],
"weighted_upstreams": [
{
"upstream": {
"type": "roundrobin",
"scheme": "https",
"pass_host": "node",
"nodes": {
"httpbin.org:443":1
}
},
"weight": 3
},
{
"weight": 2
}
]
}
]
}
},
"upstream": {
"type": "roundrobin",
"scheme": "https",
"pass_host": "node",
"nodes": {
"mock.api7.ai:443":1
}
}
}'

❶ Execute the plugin to redirect traffic only when the request contains a URL parameter name=jack, a header user-id with its value greater than 23, and another header apisix-key with its value composed of lowercase English letters.

If conditions are satisfied, 60% of the traffic should be directed to httpbin.org and the other 40% should be directed to mock.api7.ai. If conditions are not satisfied, all traffic should be directed to mock.api7.ai.

Send 10 consecutive requests that satisfy all conditions to verify:

resp=$(seq 10 | xargs -I{} curl "http://127.0.0.1:9080/headers?name=jack" -H 'user-id: 30' -H 'apisix-key: helloapisix' -sL) && \
count_httpbin=$(echo "$resp" | grep "httpbin.org" | wc -l) && \
count_mockapi7=$(echo "$resp" | grep "mock.api7.ai" | wc -l) && \
echo httpbin.org: $count_httpbin, mock.api7.ai: $count_mockapi7

You should see a response similar to the following:

httpbin.org: 6, mock.api7.ai: 4

Send 10 consecutive requests that do not satisfy the conditions to verify:

resp=$(seq 10 | xargs -I{} curl "http://127.0.0.1:9080/headers?name=random" -sL) && \
count_httpbin=$(echo "$resp" | grep "httpbin.org" | wc -l) && \
count_mockapi7=$(echo "$resp" | grep "mock.api7.ai" | wc -l) && \
echo httpbin.org: $count_httpbin, mock.api7.ai: $count_mockapi7

You should see a response similar to the following:

httpbin.org: 0, mock.api7.ai: 10

A common use case of the traffic-split plugin is to implement release strategies, such as canary release and blue-green deployment. For more plugin usage, see the plugin doc.

Label Traffic by Headers Conditionally and Proportionally

In this section, you will learn how to add headers to requests conditionally and by weights, using the enterprise traffic-label plugin.

Create a route as such:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "traffic-label-route",
"uri":"/headers",
"plugins":{
"traffic-label": {
"rules": [
{
"match": [
["uri", "==", "/headers"]
],
"actions": [
{
"set_headers": {
"X-Server-Id": 100
},
"weight": 3
},
{
"set_headers": {
"X-API-Version": "v2"
},
"weight": 2
},
{
"weight": 5
}
]
}
]
}
},
"upstream":{
"type":"roundrobin",
"nodes":{
"httpbin.org:80":1
}
}
}'

❶ 30% of the requests should have the X-Server-Id: 100 request header.

❷ 20% of the requests should have the X-API-Version: v2 request header.

❸ 50% of the requests should not have any action performed on them.

Generate 50 consecutive requests to verify the weighted actions:

resp=$(seq 50 | xargs -I{} curl "http://127.0.0.1:9080/headers" -sL) && \
count_w3=$(echo "$resp" | grep "X-Server-Id" | wc -l) && \
count_w2=$(echo "$resp" | grep "X-API-Version" | wc -l) && \
echo X-Server-Id: $count_w3, X-API-Version: $count_w2

The response shows that headers are added to requests in a weighted manner:

X-Server-Id: 15, X-API-Version: 10

For more plugin usage, see the plugin doc.

Rate Limit Traffic Conditionally

In this section, you will learn how to implement rate limiting by count conditionally, using the workflow plugin.

Create a route as such:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "workflow-route",
"uri": "/anything/*",
"plugins":{
"workflow":{
"rules":[
{
"case":[
["uri", "==", "/anything/rate-limit"],
["arg_env", "==", "v1"]
],
"actions":[
[
"limit-count",
{
"count":1,
"time_window":60,
"rejected_code":429
}
]
]
}
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'

❶ Execute the plugin to rate limit only when the request's URI path is /anything/rate-limit and it contains a URL parameter env=v1.

❷ Apply rate limiting when the rule is matched.

Generate two consecutive requests that match the condition:

curl -i "http://127.0.0.1:9080/anything/rate-limit?env=v1"

You should receive an HTTP/1.1 200 OK response and an HTTP 429 Too Many Requests response response.

Generate requests that do not match the condition:

curl -i "http://127.0.0.1:9080/anything/anything?env=v1"

You should receive HTTP/1.1 200 OK responses for all requests, as they are not rate limited.

For more plugin usage, see the plugin doc.

Next Steps

You have now learned the various ways APISIX supports conditional traffic management, using the traffic-split, traffic-label, and workflow plugins.

To meet more complex conditional traffic management requirements, see how you can create custom plugin, or use serverless plugins to execute custom code at runtime (coming soon).


API7.ai Logo

API Management for Modern Architectures with Edge, API Gateway, Kubernetes, and Service Mesh.

Product

API7 Cloud

SOC2 Type IRed Herring

Copyright © APISEVEN Ltd. 2019 – 2024. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the

Apache Software Foundation