f9045a8404
- 将 Nexus/Nexus/* 移到仓库根目录(消除双层嵌套) - 删除旧的多层空壳目录 (server/, web/, agent/, deploy/, docs/) - 将PHP前端 (web/) 合并进Nexus仓库 — 统一管理 - 部署时 git clone Nexus 仓库即可,不再需要两个仓库 目录结构: server/ ← Python FastAPI后端 web/ ← PHP前端 (install.php, config.php, etc) deploy/ ← Supervisor + Shell健康检查 docs/ ← 部署文档 tests/ ← 测试 .env ← 不在git中 (install.php生成) .gitignore ← 排除 .env, SECRETS.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
74 lines
3.0 KiB
Bash
74 lines
3.0 KiB
Bash
#!/bin/bash
|
|
# Nexus — External Health Monitor (Layer 3 of 3-tier guardian)
|
|
# Runs via crontab every minute.
|
|
# Does NOT depend on Python — even if Python completely crashes, this script works.
|
|
#
|
|
# Guardian layers:
|
|
# Layer 1: Supervisor — auto-restart crashed Python process
|
|
# Layer 2: Python self_monitor — internal Redis/MySQL/WS checks (30s)
|
|
# Layer 3: Shell health_monitor.sh — external HTTP health check (1min cron)
|
|
#
|
|
# Flow:
|
|
# 1. HTTP GET http://127.0.0.1:8600/health
|
|
# 2. If fails >= 3 consecutive times → restart via supervisorctl + Telegram alert
|
|
# 3. If restart succeeds → Telegram recovery notification
|
|
# 4. If restart fails → Telegram "needs human intervention" alert
|
|
|
|
FAIL_FILE="/tmp/nexus_health_fail_count"
|
|
MAX_FAIL=3
|
|
HEALTH_URL="http://127.0.0.1:8600/health"
|
|
SUPERVISOR_SERVICE="nexus"
|
|
|
|
# ── Read Telegram config from PHP config file (shared with Python) ──
|
|
# This avoids hardcoding Telegram credentials in this shell script
|
|
CONFIG_PHP="/www/wwwroot/api.synaglobal.vip/web/data/config.php"
|
|
|
|
BOT_TOKEN=""
|
|
CHAT_ID=""
|
|
|
|
if [ -f "$CONFIG_PHP" ]; then
|
|
BOT_TOKEN=$(grep 'TELEGRAM_BOT_TOKEN' "$CONFIG_PHP" 2>/dev/null | sed "s/.*'\(.*\)'.*/\1/" || echo "")
|
|
CHAT_ID=$(grep 'TELEGRAM_CHAT_ID' "$CONFIG_PHP" 2>/dev/null | sed "s/.*'\(.*\)'.*/\1/" || echo "")
|
|
fi
|
|
|
|
# Fallback: read from .env if config.php not yet generated (during initial setup)
|
|
if [ -z "$BOT_TOKEN" ] && [ -f "/www/wwwroot/api.synaglobal.vip/.env" ]; then
|
|
BOT_TOKEN=$(grep '^NEXUS_TELEGRAM_BOT_TOKEN=' /www/wwwroot/api.synaglobal.vip/.env 2>/dev/null | cut -d'=' -f2- || echo "")
|
|
CHAT_ID=$(grep '^NEXUS_TELEGRAM_CHAT_ID=' /www/wwwroot/api.synaglobal.vip/.env 2>/dev/null | cut -d'=' -f2- || echo "")
|
|
fi
|
|
|
|
send_telegram() {
|
|
[ -z "$BOT_TOKEN" ] || [ -z "$CHAT_ID" ] && return 1
|
|
curl -sf --max-time 10 "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
|
|
-d chat_id="$CHAT_ID" \
|
|
-d text="$1" \
|
|
-d parse_mode=HTML \
|
|
> /dev/null 2>&1
|
|
}
|
|
|
|
# ── Health Check ──
|
|
if ! curl -sf --max-time 5 "$HEALTH_URL" > /dev/null 2>&1; then
|
|
# Python is NOT responding
|
|
FAIL=$(cat "$FAIL_FILE" 2>/dev/null || echo "0")
|
|
FAIL=$((FAIL + 1))
|
|
echo "$FAIL" > "$FAIL_FILE"
|
|
|
|
if [ "$FAIL" -ge "$MAX_FAIL" ]; then
|
|
# Consecutive failures >= threshold → attempt restart
|
|
send_telegram "🔴 <b>Nexus后端连续${MAX_FAIL}次无响应</b>\n正在通过Supervisor自动重启..."
|
|
supervisorctl restart "$SUPERVISOR_SERVICE" > /dev/null 2>&1
|
|
sleep 5
|
|
|
|
# Verify restart
|
|
if curl -sf --max-time 5 "$HEALTH_URL" > /dev/null 2>&1; then
|
|
send_telegram "🟢 <b>Nexus后端已恢复</b>\nSupervisor重启成功"
|
|
echo "0" > "$FAIL_FILE"
|
|
else
|
|
send_telegram "🔴 <b>Nexus重启后仍未恢复!请人工介入</b>\nSupervisor重启失败,需要手动检查"
|
|
# Don't reset fail count — keep retrying each cron cycle
|
|
fi
|
|
fi
|
|
else
|
|
# Python is responding normally
|
|
echo "0" > "$FAIL_FILE"
|
|
fi |