diff --git a/deploy/restart-all.sh b/deploy/restart-all.sh index 788a5d8d3..c9e6df28b 100644 --- a/deploy/restart-all.sh +++ b/deploy/restart-all.sh @@ -182,22 +182,62 @@ if ! /usr/sbin/nginx -t -c "$NGINX_CONF"; then exit 1 fi -if pgrep -u "$(whoami)" -f "nginx: master" >/dev/null; then - echo "平滑重载前端 Nginx 服务..." +NGINX_PID_FILE="$NGINX_DIR/nginx.pid" +IS_RUNNING=0 +TARGET_NGINX_PID="" +# 1. 检查专属 PID 文件并校验进程归属 +if [ -f "$NGINX_PID_FILE" ]; then + RECORDED_PID=$(cat "$NGINX_PID_FILE" 2>/dev/null | tr -d '[:space:]') + if [ -n "$RECORDED_PID" ] && kill -0 "$RECORDED_PID" 2>/dev/null; then + if ps -p "$RECORDED_PID" -o args= 2>/dev/null | grep -F -- "$NGINX_CONF" >/dev/null; then + IS_RUNNING=1 + TARGET_NGINX_PID="$RECORDED_PID" + else + echo "警告:$NGINX_PID_FILE 中的 PID $RECORDED_PID 不属于本实例,清理失效 PID 文件..." + rm -f "$NGINX_PID_FILE" + fi + else + echo "发现已退出的过期 Nginx PID (${RECORDED_PID:-空}),清理失效 PID 文件..." + rm -f "$NGINX_PID_FILE" + fi +fi + +# 2. 兜底探测:仅按专用配置文件路径查找存活 master 进程 +if [ "$IS_RUNNING" -eq 0 ]; then + FALLBACK_PID=$(pgrep -u "$(whoami)" -f "nginx: master.*$NGINX_CONF" | head -n 1) + if [ -n "$FALLBACK_PID" ] && kill -0 "$FALLBACK_PID" 2>/dev/null; then + echo "发现运行中但缺少有效 PID 文件的专属 Nginx 实例 (PID: $FALLBACK_PID),回填 PID..." + echo "$FALLBACK_PID" > "$NGINX_PID_FILE" + IS_RUNNING=1 + TARGET_NGINX_PID="$FALLBACK_PID" + fi +fi + +# 3. 根据实际存活状态执行平滑重载或全新启动 +if [ "$IS_RUNNING" -eq 1 ]; then + echo "专属 Nginx 服务运行中 (PID: $TARGET_NGINX_PID),执行平滑重载..." if ! /usr/sbin/nginx -c "$NGINX_CONF" -s reload; then - echo "错误:Nginx 平滑重载失败" + echo "错误:专属 Nginx 平滑重载失败" exit 1 fi else - echo "启动前端 Nginx 服务..." - + echo "未发现运行中的专属 Nginx 实例,执行全新启动..." + rm -f "$NGINX_PID_FILE" if ! /usr/sbin/nginx -c "$NGINX_CONF"; then - echo "错误:Nginx 启动失败" + echo "错误:专属 Nginx 启动失败" exit 1 fi fi +# 4. 验证专属 Nginx 实例运行状态 +sleep 1 +FINAL_PID=$(cat "$NGINX_PID_FILE" 2>/dev/null | tr -d '[:space:]') +if [ -z "$FINAL_PID" ] || ! kill -0 "$FINAL_PID" 2>/dev/null; then + echo "错误:Nginx 启动或重载后未检测到存活的 master 进程" + exit 1 +fi + echo "=== 4. 执行生产环境自动化冒烟测试 (Production Smoke Gate) ===" SMOKE_PASS=1