蓝绿部署策略
双环境切换,即时回滚、流量迁移与数据库迁移安全。
CI/CD进阶
为什么
蓝绿保持两个相同生产环境,原子地迁移 100% 流量。新版本(绿)在蓝服务实时流量时暂存并冒烟测试;切换瞬时,回滚只需切回。零停机,无部分推出不一致。
何时使用
无状态 web 应用需即时回滚且能负担 2x 基础设施时用蓝绿。避免长时 WebSocket(切换断连)或无支持目标交换的负载均衡器的应用。
如何做
1. 配两个环境 — blue(当前线上)和 green(空闲),相同基础设施 + 配置
2. 部署到 green — CI/CD 目标 green,跑迁移(仅向前、向后兼容)
3. 冒烟测试 green — 直接访问 green URL(绕过 LB),跑健康检查 + 关键用户流程
4. 预热 green — 扩实例,跑缓存预热,首请求不冷
5. 切流量 — LB 将目标组从 blue 换到 green(ALB 目标组交换,1 次 API 调用)
6. 监控 — 看错误率 + 延迟 5-10 分钟;飙升则切回 blue(即时回滚)
7. 退役 blue — 保留回滚窗口(如 1h),然后缩到 0 或复用为下个 green
8. 数据库 — 扩展/收缩模式:green 加新列(扩展),blue 仍写旧;切换后迁移写入(收缩)
示例
# deploy.sh — 用 AWS ALB 目标组做蓝绿
#!/bin/bash
set -euo pipefail
BLUE_TG="arn:aws:elasticloadbalancing:...:targetgroup/blue/abc"
GREEN_TG="arn:aws:elasticloadbalancing:...:targetgroup/green/xyz"
LISTENER_ARN="arn:aws:elasticloadbalancing:...:listener/app/myapp/80/def"
# 1. 部署新镜像到 green(ECS 服务自动扩缩)
aws ecs update-service --service myapp-green --force-new-deployment
aws ecs wait services-stable --services myapp-green
# 2. 直接冒烟测试 green(经其内部 DNS)
GREEN_URL="http://myapp-green.internal:3000/health"
for i in {1..10}; do
curl -sf "$GREEN_URL" && break || sleep 5
done
# 3. 将监听器默认动作换到 green 目标组
aws elbv2 modify-listener --listener-arn "$LISTENER_ARN" \
--default-actions Type=forward,TargetGroupArn="$GREEN_TG"
echo "流量已切到 green。监控 10 分钟..."
START=$(date +%s)
while [ $(( $(date +%s) - START )) -lt 600 ]; do
ERRORS=$(aws cloudwatch get-metric-statistics \
--namespace AWS/ApplicationELB --metric-name HTTPCode_ELB_5XX \
--dimensions Name=LoadBalancer,Value=app/myapp/80 \
--start-time $(date -u -d '5 min ago' +%FT%TZ) \
--end-time $(date -u +%FT%TZ) --period 60 --statistics Sum | jq '.Datapoints[0].Sum')
[ "${ERRORS:-0}" -gt 10 ] && { echo "错误飙升!回滚"; aws elbv2 modify-listener --listener-arn "$LISTENER_ARN" --default-actions Type=forward,TargetGroupArn="$BLUE_TG"; exit 1; }
sleep 30
done
echo "蓝绿部署成功"
常见问题
- ⚠数据库迁移破坏 blue — green 跑破坏性迁移时 blue 仍服务流量
- ⚠粘性会话切换断裂 — 登录 blue 的用户在 green 401(不同会话存储)
- ⚠无监控窗口 — 切换后团队离开,30 分钟后才发现生产错误飙升
- ⚠2x 基础设施常开 — green 部署间也 24/7 保留,浪费预算
最佳实践
- ✓用扩展/收缩数据库迁移 — green 加(扩展),切换,下个部署删旧(收缩)
- ✓blue 与 green 共享会话存储(Redis)— 粘性会话切换存活
- ✓自动化 10 分钟监控窗口 — 错误率阈值脚本回滚,无需人工
- ✓部署间 green 缩到 0 — 仅部署时拉起,省 50% 基础设施成本
常见问题解答
蓝绿和滚动更新有什么不同?
蓝绿一次性切换所有流量到新(绿)环境,旧(蓝)保持待命以便即时回滚。滚动更新逐步替换实例——更慢但只需备用容量,无需完整重复环境。
蓝绿中如何处理数据库迁移?
迁移必须向后兼容——蓝和绿切换期间对同一 DB 运行。部署前应用加性迁移(新列),蓝退役后才应用破坏性迁移(删列)。
绿环境健康检查失败怎么办?
流量留在蓝——切换不发生。路由流量前监控绿健康端点。设自动回滚:绿前 5 分钟错误率超 1% 则自动切回蓝。
如何经济地管理两环境?
蓝全容量(服务流量),绿最小规模(1 实例)直到健康检查通过,再扩绿缩蓝。相比永久双全容量,成本减半。
蓝绿何时不是好选择?
应用用 WebSocket 或长连接时——即时切换断所有活跃会话。改用滚动更新或金丝雀策略。蓝绿最适合无状态 HTTP 请求/响应应用。