跳到主要内容
版本:3.10.x

API7 网关 AI Agent Skill:traffic-split 插件

概览

traffic-split 插件会根据自定义规则(match)和加权分配(weighted_upstreams),将部分流量动态转发到不同的上游服务。它适用于灰度发布、蓝绿发布和 A/B 测试,且无需修改 DNS 或负载均衡器配置。

适用场景

  • 灰度发布:逐步将流量切换到新版本(10% → 50% → 100%)。
  • 蓝绿发布:根据请求头或 Cookie 切换流量。
  • A/B 测试:根据用户属性(请求头、查询参数或 Cookie)拆分流量。
  • 功能开关:将特定用户路由到功能分支。
  • 多版本 API:同时运行多个后端版本。

插件配置参考(路由/服务)

顶层配置

字段类型是否必填默认值说明
rulesarray[object]流量拆分规则列表。每条规则都可以包含可选的 match,并且必须包含 weighted_upstreams

rules[].match

字段类型是否必填默认值说明
matcharray[object][]激活此规则的条件。为空表示无条件匹配(所有流量都按权重分配)。
match[].varsarray[array]变量表达式:["variable", "operator", "value"]。使用 NGINX 变量。同一对象中的多个变量表示 AND,match 中的多个对象表示 OR。

运算符:==~=><>=<=~~(正则匹配)、!~~inhas!。详见 lua-resty-expr

常用变量:arg_name(查询参数)、http_header-name(请求头)、cookie_name(Cookie 值)。

rules[].weighted_upstreams[]

字段类型是否必填默认值说明
upstreamobject内联上游配置(见下文)。
weightinteger1此上游的流量权重。

如果只设置 weight(没有内联 upstream),流量将转发到路由所关联服务的上游。

内联上游对象

字段类型是否必填默认值说明
typestring"roundrobin"负载均衡类型:"roundrobin""chash"
nodesarray后端节点,格式为 [{host, port, weight}]
timeoutobject15(秒){"connect": N, "send": N, "read": N}
pass_hoststring"pass""pass" 表示客户端 Host,"node" 表示上游节点,"rewrite" 表示使用 upstream_host
upstream_hoststring自定义 Host 请求头。仅在 pass_host: "rewrite" 时生效。
namestring上游的可读名称。

内联加权上游不支持service_namediscovery_typechecksretriesretry_timeout。如有可能,请将共享上游行为保留在关联的服务中。

分步指南:在路由上启用 traffic-split

1. 灰度发布:将 20% 流量发送到新版本

在网关组 default 中配置 20/80 分流:

a7 service create --gateway-group default -f - <<'EOF'
{
"id": "stable-api-service",
"name": "stable-api-service",
"upstream": {
"type": "roundrobin",
"nodes": [{"host": "backend-v1", "port": 8080, "weight": 1}]
}
}
EOF

a7 route create --gateway-group default -f - <<'EOF'
{
"id": "canary-release",
"uri": "/api/*",
"service_id": "stable-api-service",
"plugins": {
"traffic-split": {
"rules": [
{
"weighted_upstreams": [
{
"upstream": {
"name": "new-version-v2",
"type": "roundrobin",
"nodes": [{"host": "backend-v2", "port": 8080, "weight": 1}]
},
"weight": 2
},
{
"weight": 8
}
]
}
]
}
}
}
EOF

结果:20% 的流量发送到 backend-v2,80% 的流量发送到 backend-v1(路由默认上游)。

2. 蓝绿发布:基于请求头切换

a7 service create --gateway-group prod -f - <<'EOF'
{
"id": "blue-api-service",
"name": "blue-api-service",
"upstream": {
"type": "roundrobin",
"nodes": [{"host": "blue-backend", "port": 8080, "weight": 1}]
}
}
EOF

a7 route create --gateway-group prod -f - <<'EOF'
{
"id": "blue-green",
"uri": "/api/*",
"service_id": "blue-api-service",
"plugins": {
"traffic-split": {
"rules": [
{
"match": [
{
"vars": [
["http_x-canary", "==", "true"]
]
}
],
"weighted_upstreams": [
{
"upstream": {
"name": "green-env",
"type": "roundrobin",
"nodes": [{"host": "green-backend", "port": 8080, "weight": 1}]
},
"weight": 1
}
]
}
]
}
}
}
EOF

结果:包含请求头 x-canary: true 的请求发送到绿色环境,其他请求发送到蓝色环境。

3. 将灰度比例提高到 50%

a7 route update canary-release --gateway-group default -f - <<'EOF'
{
"plugins": {
"traffic-split": {
"rules": [
{
"weighted_upstreams": [
{
"upstream": {
"name": "new-version-v2",
"type": "roundrobin",
"nodes": [{"host": "backend-v2", "port": 8080, "weight": 1}]
},
"weight": 5
},
{
"weight": 5
}
]
}
]
}
}
}
EOF

常见模式

通过查询参数进行 A/B 测试

{
"plugins": {
"traffic-split": {
"rules": [
{
"match": [
{
"vars": [
["arg_variant", "==", "B"]
]
}
],
"weighted_upstreams": [
{
"upstream": {
"name": "variant-B",
"type": "roundrobin",
"nodes": [{"host": "variant-b", "port": 8080, "weight": 1}]
}
}
]
}
]
}
}
}

带有 ?variant=B 的请求会发送到 B 版本后端。

多规则路由(OR 逻辑)

{
"plugins": {
"traffic-split": {
"rules": [
{
"match": [{"vars": [["http_x-api-id", "==", "1"]]}],
"weighted_upstreams": [
{"upstream": {"type": "roundrobin", "nodes": [{"host": "svc-a", "port": 8080, "weight": 1}]}}
]
},
{
"match": [{"vars": [["http_x-api-id", "==", "2"]]}],
"weighted_upstreams": [
{"upstream": {"type": "roundrobin", "nodes": [{"host": "svc-b", "port": 8080, "weight": 1}]}}
]
}
]
}
}
}

健康检查注意事项

{
"plugins": {
"traffic-split": {
"rules": [
{
"weighted_upstreams": [
{
"upstream": {"type": "roundrobin", "nodes": [{"host": "canary", "port": 8080, "weight": 1}]},
"weight": 2
},
{
"weight": 8
}
]
}
]
}
}
}

当前 API7 企业版不会通过 a7 暴露独立上游的增删改查操作。进行流量拆分时,优先使用内联加权上游;如有需要,请在服务上游配置中保留健康检查设置。

匹配逻辑参考

结构逻辑
一个 vars 数组中的多个条目AND:必须全部匹配
match 数组中的多个对象OR:任意对象匹配即可
match 为空或未设置 match无条件:始终应用权重

故障排查

现象原因解决方法
流量比例不准确轮询算法会造成轻微偏差这是预期行为;经过足够多的请求后,比例会逐渐接近设定值
匹配规则未触发变量名错误或运算符不匹配请求头使用 http_header-name,查询参数使用 arg_name
健康检查未生效服务上游未配置健康检查将稳定后端的健康检查设置移至服务上游配置
所有流量都发送到默认上游匹配条件始终不成立使用 a7 route get 调试,并核对请求头或参数名称
权重为 0 仍未阻止流量权重为 0 表示“永不转发”到该上游这是正确行为;将上游权重设为 0 即可排除该上游
配置未生效指定了错误的网关组确保 --gateway-group 与目标集群一致

配置同步示例

version: "1"
services:
- id: stable-api-service
name: stable-api-service
upstream:
type: roundrobin
nodes:
- host: stable-backend
port: 8080
weight: 1
routes:
- id: canary-api
uri: /api/*
service_id: stable-api-service
plugins:
traffic-split:
rules:
- weighted_upstreams:
- upstream:
type: roundrobin
nodes:
- host: canary-backend
port: 8080
weight: 1
weight: 2
- weight: 8

本页面由 api7/a7 仓库中的 a7-plugin-traffic-split/SKILL.md 生成。你可以在 AI Agent Skills 页面查看所有技能。