跳到主要内容

条件流量管理

条件流量管理是指根据每个请求的某些特征(例如请求标头、URI 参数或 URI 路径)执行特定操作的能力。这使得人们能够实施动态和灵活的路由、限流限速或其他操作,从而允许根据应用程序或系统的特定需求对网关的行为进行细粒度控制和自定义。

本指南将向你展示如何使用 traffic-splittraffic-labelworkflow 插件在 APISIX 中有条件地管理流量。

前置条件

  • 安装 Docker
  • 安装 cURL 以向服务发送请求进行验证。
  • 按照 快速入门教程 在 Docker 或 Kubernetes 中启动一个新的 APISIX 实例。

按条件和比例转发流量

在本节中,你将了解如何使用 traffic-split 插件按条件和权重将流量转发到不同的上游服务。

创建如下路由:

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": [
{
// Annotate 1
"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
}
}
}'

❶ 仅当请求包含 URL 参数 name=jack、标头 user-id 的值大于 23 且另一个标头 apisix-key 的值由小写英文字母组成时,才执行插件以重定向流量。

如果满足条件,60% 的流量应指向 httpbin.org,另外 40% 应指向 mock.api7.ai。如果不满足条件,所有流量应指向 mock.api7.ai

发送 10 个满足所有条件的连续请求以进行验证:

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

你应该看到类似以下的响应:

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

发送 10 个不满足条件的连续请求以进行验证:

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

你应该看到类似以下的响应:

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

traffic-split 插件的一个常见用例是实施发布策略,例如金丝雀发布和蓝绿部署。有关更多插件用法,请参阅 插件文档

按条件和比例标记流量标头

在本节中,你将了解如何使用企业版 traffic-label 插件按条件和权重向请求添加标头。

创建如下路由:

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
},
// Annotate 1
"weight": 3
},
{
"set_headers": {
"X-API-Version": "v2"
},
// Annotate 2
"weight": 2
},
{
// Annotate 3
"weight": 5
}
]
}
]
}
},
"upstream":{
"type":"roundrobin",
"nodes":{
"httpbin.org:80":1
}
}
}'

❶ 30% 的请求应具有 X-Server-Id: 100 请求头。

❷ 20% 的请求应具有 X-API-Version: v2 请求头。

❸ 50% 的请求不应对其执行任何操作。

生成 50 个连续请求以验证加权操作:

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

响应显示标头以加权方式添加到请求中:

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

有关更多插件用法,请参阅 插件文档

有条件地对流量进行限流限速

在本节中,你将了解如何使用 workflow 插件有条件地按计数实施限流限速。

创建如下路由:

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":[
// Annotate 1
["uri", "==", "/anything/rate-limit"],
["arg_env", "==", "v1"]
],
"actions":[
[
// Annotate 2
"limit-count",
{
"count":1,
"time_window":60,
"rejected_code":429
}
]
]
}
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'

❶ 仅当请求的 URI 路径为 /anything/rate-limit 且包含 URL 参数 env=v1 时,才执行插件以进行限流限速。

❷ 匹配规则时应用限流限速。

生成两个符合条件的连续请求:

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

你应该收到一个 HTTP/1.1 200 OK 响应和一个 HTTP 429 Too Many Requests 响应。

生成不符合条件的请求:

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

你应该收到所有请求的 HTTP/1.1 200 OK 响应,因为它们没有被限流限速。

有关更多插件用法,请参阅 插件文档

下一步

你现在已经了解了 APISIX 支持条件流量管理的各种方式,使用 traffic-splittraffic-labelworkflow 插件。

为了满足更复杂的条件流量管理需求,请查看如何 创建自定义插件,或使用 无服务器函数插件 在运行时执行自定义代码。