#!/bin/bash # 灰度回滚脚本:切回全量稳定版本,停止 canary 容器 # 用法: ./scripts/rollback_gray.sh set -euo pipefail NGINX_CONF="${NGINX_CONF:-/etc/nginx/sites-enabled/00-xiaoxia-saas}" CANARY_API="${CANARY_API:-xiaoxia-api-canary}" CANARY_WEB="${CANARY_WEB:-xiaoxia-web-canary}" echo "============================================" echo " 灰度回滚" echo " 目标: 全量切回稳定版本" echo "============================================" # 1. 找最近的灰度备份 echo "" echo ">>> 查找最近的灰度备份..." LATEST_BAK=$(ls -t "${NGINX_CONF}".bak.gray.* 2>/dev/null | head -1 || true) if [[ -z "$LATEST_BAK" ]]; then echo " 未找到灰度备份,尝试手动移除 upstream 配置..." # 手动回滚:移除 upstream 块,把 proxy_pass 改回 127.0.0.1 TMP_CONF=$(mktemp) # 移除 upstream 块(从 "# Gray release upstreams" 到空行结束) awk ' /^# Gray release upstreams/ { skip=1; next } skip && /^$/ && !found_first_empty { found_first_empty=1; next } skip && found_first_empty && /^$/ { skip=0; found_first_empty=0; next } skip { next } { print } ' "$NGINX_CONF" > "$TMP_CONF" # 把 upstream 名改回 IP sed -i 's|proxy_pass http://saas_api_backend|proxy_pass http://127.0.0.1:8001|g' "$TMP_CONF" sed -i 's|proxy_pass http://saas_web_backend/|proxy_pass http://127.0.0.1:3002/|g' "$TMP_CONF" mv "$TMP_CONF" "$NGINX_CONF" else echo " 从备份恢复: $LATEST_BAK" cp "$LATEST_BAK" "$NGINX_CONF" fi # 2. 测试并 reload nginx echo "" echo ">>> Nginx 测试 & reload..." if ! nginx -t 2>&1; then echo " ❌ Nginx 配置测试失败!请检查" exit 1 fi nginx -s reload echo " ✅ Nginx 已回滚,全量切回稳定版本" # 3. 停止 canary 容器(延迟停止,保留30分钟便于排查) echo "" echo ">>> Canary 容器将在30分钟后停止(便于排查)" echo " 立即停止请执行: docker rm -f $CANARY_API $CANARY_WEB" # 30分钟后停止(后台执行,不阻塞脚本) ( sleep 1800 for c in "$CANARY_API" "$CANARY_WEB"; do if docker ps --format '{{.Names}}' | grep -q "^${c}$"; then docker stop "$c" >/dev/null 2>&1 && docker rm "$c" >/dev/null 2>&1 echo "[$(date)] 已停止 canary 容器: $c" fi done ) & echo "" echo "============================================" echo " ✅ 灰度回滚完成" echo " 流量已全部切回稳定版本" echo " Canary 容器: 30分钟后自动清理" echo "============================================"