跳到主要内容

a6-plugin-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[]

字段类型必填默认描述
upstream_id字符串/整数预配置的上游对象的ID. 用这个来进行健康检查、重试等.
upstream对象内置上游配置(见下文)。
weight整数1分配给该上游的流量权重

如果只设置了 weight(未设置 upstreamupstream_id),流量将进入路由的默认上游。

内联上游对象

字段类型是否必填默认值说明
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% 流量发送到新版本

配置 20/80 流量分配:

a6 route create -f - <<'EOF'
{
"id": "canary-release",
"uri": "/api/*",
"plugins": {
"traffic-split": {
"rules": [
{
"weighted_upstreams": [
{
"upstream": {
"name": "new-version-v2",
"type": "roundrobin",
"nodes": {
"backend-v2:8080": 1
}
},
"weight": 2
},
{
"weight": 8
}
]
}
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"backend-v1:8080": 1
}
}
}
EOF

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

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

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

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

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

a6 route update canary-release -f - <<'EOF'
{
"plugins": {
"traffic-split": {
"rules": [
{
"weighted_upstreams": [
{
"upstream": {
"name": "new-version-v2",
"type": "roundrobin",
"nodes": {
"backend-v2:8080": 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": {"variant-b:8080": 1}
}
}
]
}
]
}
}
}

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

多规则路由(OR 逻辑)

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

使用上游编号进行健康检查

{
"plugins": {
"traffic-split": {
"rules": [
{
"weighted_upstreams": [
{
"upstream_id": "canary-upstream",
"weight": 2
},
{
"weight": 8
}
]
}
]
}
}
}

使用a6 upstream create预先创建上游,以配置运行状况检查、重试和其他高级设置。

多重条件和匹配

{
"match": [
{
"vars": [
["arg_name", "==", "jack"],
["http_user-id", ">", "23"],
["http_x-env", "~~", "^(staging|canary)$"]
]
}
]
}

所有三个条件都必须为真(并且逻辑位于单个vars数组中)。

匹配逻辑参考

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

故障排查

症状原因解决方法
流量比例不精确轮询算法会产生轻微偏差这是预期行为;请求数量增加后,实际比例会逐渐接近配置值
匹配规则未触发变量名称错误或运算符不匹配请求头使用 http_header-name,查询参数使用 arg_name
健康检查未生效内联上游不支持 checks使用 upstream_id 引用已配置健康检查的上游
所有流量都进入默认上游匹配条件始终不成立使用 a6 route get 调试,并核对请求头和参数名称
权重为 0 的上游仍有流量误解了权重语义权重 0 表示不向该上游转发流量,可用于排除该上游

配置同步示例

version: "1"
routes:
- id: canary-api
uri: /api/*
plugins:
traffic-split:
rules:
- weighted_upstreams:
- upstream_id: canary-upstream
weight: 2
- weight: 8
upstream_id: stable-upstream
upstreams:
- id: stable-upstream
type: roundrobin
nodes:
"stable-backend:8080": 1
- id: canary-upstream
type: roundrobin
nodes:
"canary-backend:8080": 1

本文根据 api7/a6 仓库中的 a6-plugin-traffic-split/SKILL.md 生成。可在 AI Agent Skills 页面浏览全部 Skill。