跳到主要内容

a6-recipe-blue-green

概览

蓝绿发布维护两套相同的生产环境(蓝色和绿色)。任何时刻仅有一套环境承载线上流量。将新版本部署到空闲环境并完成测试后,可以立即切换流量;如果出现问题,也可以快速回滚。

本方案通过 a6 CLI 管理 APISIX 路由和上游,实现蓝绿发布。

适用场景

  • 通过即时回滚实现零停机部署
  • 您有两个可以交换的相同环境
  • 您想在切换之前使用内部流量测试新版本
  • 您需要一个可审计、可编写脚本的部署流程

方法 A:切换上游(最简单)

更新路由的 upstream_id,使其指向另一套环境对应的上游。

1. 创建两个上游

a6 upstream create -f - <<'EOF'
{
"id": "blue",
"type": "roundrobin",
"nodes": {
"blue-backend-1:8080": 1,
"blue-backend-2:8080": 1
}
}
EOF

a6 upstream create -f - <<'EOF'
{
"id": "green",
"type": "roundrobin",
"nodes": {
"green-backend-1:8080": 1,
"green-backend-2:8080": 1
}
}
EOF

2. 创建指向蓝色环境的路由

a6 route create -f - <<'EOF'
{
"id": "api",
"uri": "/api/*",
"upstream_id": "blue"
}
EOF

3. 部署并测试绿色环境

将新版本部署到绿色环境,并通过内部流量完成验证。

4. 切换到绿色环境

a6 route update api -f - <<'EOF'
{
"upstream_id": "green"
}
EOF

流量即时切换,无需停机。

5. 回滚到蓝色环境(如有需要)

a6 route update api -f - <<'EOF'
{
"upstream_id": "blue"
}
EOF

方法 B:使用 traffic-split(基于请求头测试)

在全量切换前,使用 traffic-split 插件将带有特定请求头的流量转发到绿色环境进行验证。

1. 创建流量拆分路由

a6 route create -f - <<'EOF'
{
"id": "api",
"uri": "/api/*",
"plugins": {
"traffic-split": {
"rules": [
{
"match": [
{
"vars": [["http_x-env", "==", "green"]]
}
],
"weighted_upstreams": [
{
"upstream_id": "green",
"weight": 1
}
]
}
]
}
},
"upstream_id": "blue"
}
EOF

2. 在内部验证绿色环境

curl -H "x-env: green" http://gateway:9080/api/health

3. 全量切换——移除流量拆分并切换上游

a6 route update api -f - <<'EOF'
{
"plugins": {},
"upstream_id": "green"
}
EOF

方法 C:同步声明式配置

config.yaml——蓝色环境承载流量

version: "1"
upstreams:
- id: blue
type: roundrobin
nodes:
"blue-backend-1:8080": 1
"blue-backend-2:8080": 1
- id: green
type: roundrobin
nodes:
"green-backend-1:8080": 1
"green-backend-2:8080": 1
routes:
- id: api
uri: /api/*
upstream_id: blue # ← change to "green" to switch

切换前预览变更

# Edit config.yaml: change upstream_id to "green"
a6 config diff -f config.yaml

应用切换

a6 config sync -f config.yaml

部署脚本示例

#!/bin/bash
set -euo pipefail

CURRENT=$(a6 route get api -o json | jq -r '.upstream_id')
TARGET=$([ "$CURRENT" = "blue" ] && echo "green" || echo "blue")

echo "Current: $CURRENT → Switching to: $TARGET"

# Switch
a6 route update api -f - <<EOF
{"upstream_id": "$TARGET"}
EOF

echo "Switched to $TARGET. Verifying..."

# Health check
if curl -sf http://gateway:9080/api/health > /dev/null; then
echo "✅ $TARGET is healthy"
else
echo "❌ $TARGET unhealthy, rolling back to $CURRENT"
a6 route update api -f - <<EOF
{"upstream_id": "$CURRENT"}
EOF
exit 1
fi

故障排查

症状原因解决方法
切换后返回 502新环境尚未就绪切换前检查健康检查端点;必要时立即回滚
流量仍然进入旧环境路由配置未更新或 DNS 缓存APISIX 路由会立即生效;使用 a6 route get 核对当前配置
无法回滚未记录原上游切换前始终记录当前状态
切换时连接中断旧上游存在长时间运行的请求APISIX 会优雅处理进行中的请求,现有连接可继续完成

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