Files
xiaoxia-saas/scripts/rollback_gray.sh
xiaoxia-bot 34336b2907
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Successful in 39s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 1m12s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m51s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Build Production Runtime Images (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 1m25s
feat(ci): 新增发布与灰度部署脚本
- release.sh: 一键发布脚本(打tag + 触发CI构建 + 灰度提示)
- gray_deploy.sh: 灰度发布脚本(canary容器 + nginx权重切流)
- rollback_gray.sh: 灰度回滚脚本(nginx回滚 + canary清理)
- 更新 rollback.sh 占位符为生产环境适配版

灰度范围:API + Web(Nginx upstream 权重)
Worker 暂不支持灰度(队列消费无法按比例切流)
2026-07-14 13:09:27 +08:00

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 "============================================"