def6ee2363
CI/CD Pipeline / Validate Code Quality And Tests (push) Successful in 46s
CI/CD Pipeline / Unit Tests (push) Successful in 1m40s
CI/CD Pipeline / Frontend Lint (push) Successful in 2m52s
CI/CD Pipeline / Build Production Runtime Images (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Integration Tests (push) Successful in 1m42s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (push) Successful in 16m34s
CI/CD Pipeline / Staging E2E Tests (push) Successful in 2m52s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 3m55s
合并PR #316:新增release.sh / gray_deploy.sh / rollback_gray.sh三个脚本,适配生产环境架构(nginx upstream权重 + canary容器)
78 lines
2.5 KiB
Bash
Executable File
78 lines
2.5 KiB
Bash
Executable File
#!/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 "============================================"
|