#!/bin/bash # 改进的服务关机机制 # 基于关机测试结果优化 set -e echo "================================================" echo "改进的服务关机机制" echo "时间: $(date)" echo "================================================" # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log() { echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" } success() { echo -e "${GREEN}✓${NC} $1" } warning() { echo -e "${YELLOW}⚠${NC} $1" } error() { echo -e "${RED}✗${NC} $1" } # 检查是否以正确用户运行 if [ "$(whoami)" != "accusys" ]; then error "请以 'accusys' 用户运行此脚本" exit 1 fi # 步骤1: 停止所有 AI 处理器 log "步骤1: 停止所有 AI 处理器..." ai_processors=( "asr_processor" "ocr_processor" "yolo_processor" "face_processor" "pose_processor" "cut_processor" "asrx_processor" "caption_processor" "story_processor" ) for processor in "${ai_processors[@]}"; do if pgrep -f "$processor" >/dev/null; then log " 停止 $processor..." pkill -TERM -f "$processor" sleep 2 if pgrep -f "$processor" >/dev/null; then warning " $processor 仍在运行,发送 SIGKILL..." pkill -KILL -f "$processor" fi success " $processor 已停止" fi done # 步骤2: 停止 Momentry 服务 log "步骤2: 停止 Momentry 服务..." momentry_services=( "momentry server" "momentry worker" "momentry_playground" ) for service in "${momentry_services[@]}"; do if pgrep -f "$service" >/dev/null; then log " 停止 $service..." pkill -TERM -f "$service" sleep 3 if pgrep -f "$service" >/dev/null; then warning " $service 仍在运行,发送 SIGKILL..." pkill -KILL -f "$service" fi success " $service 已停止" fi done # 步骤3: 停止 MCP 服务器 log "步骤3: 停止 MCP 服务器..." mcp_servers=( "mcp-server-redis" "mcp-server-postgres" "mcp-server-filesystem" "mcp-server-qdrant" "mongodb-mcp-server" "gitea-mcp-server" ) for server in "${mcp_servers[@]}"; do if pgrep -f "$server" >/dev/null; then pkill -f "$server" sleep 1 success "MCP 服务器 $server 已停止" fi done # 步骤4: 停止应用服务 (不需要 sudo) log "步骤4: 停止应用服务..." # PHP-FPM if pgrep -f "php-fpm" >/dev/null; then log " 停止 PHP-FPM..." pkill -TERM php-fpm sleep 3 success " PHP-FPM 已停止" fi # n8n if pgrep -f "n8n" >/dev/null; then log " 停止 n8n..." pkill -TERM -f "n8n" sleep 2 success " n8n 已停止" fi # Ollama if pgrep -f "ollama" >/dev/null; then log " 停止 Ollama..." pkill -TERM ollama sleep 2 success " Ollama 已停止" fi # Gitea if pgrep -f "gitea web" >/dev/null; then log " 停止 Gitea..." pkill -TERM -f "gitea web" sleep 3 success " Gitea 已停止" fi # SFTPGo if pgrep -f "sftpgo serve" >/dev/null; then log " 停止 SFTPGo..." pkill -TERM -f "sftpgo serve" sleep 2 success " SFTPGo 已停止" fi # 步骤5: 停止需要 sudo 的服务 log "步骤5: 停止需要 sudo 权限的服务..." # Caddy (需要 sudo) if pgrep -f "caddy" >/dev/null; then log " 停止 Caddy (需要 sudo)..." echo "accusys" | sudo -S pkill -TERM caddy 2>/dev/null || true sleep 3 if pgrep -f "caddy" >/dev/null; then warning " Caddy 仍在运行,使用 sudo 强制停止..." echo "accusys" | sudo -S pkill -KILL -f "caddy" 2>/dev/null || true fi success " Caddy 已停止" fi # 步骤6: 停止数据库服务 (改进版本) log "步骤6: 停止数据库服务..." # Redis - 改进的停止方法 if pgrep -f "redis-server" >/dev/null; then log " 停止 Redis..." # 尝试优雅停止 redis-cli shutdown 2>/dev/null || true sleep 5 # 如果仍在运行,发送 TERM 信号 if pgrep -f "redis-server" >/dev/null; then warning " Redis 仍在运行,发送 TERM 信号..." pkill -TERM redis-server sleep 3 fi # 如果仍在运行,强制停止 if pgrep -f "redis-server" >/dev/null; then warning " Redis 仍在运行,强制停止..." pkill -KILL redis-server fi success " Redis 已停止" fi # PostgreSQL - 改进的停止方法 if pgrep -f "postgres" >/dev/null; then log " 停止 PostgreSQL..." # 方法1: 使用 pg_ctl (快速模式) pg_ctl -D /Users/accusys/momentry/var/postgresql stop -m fast 2>/dev/null || true sleep 10 # 增加等待时间 # 方法2: 如果仍在运行,发送 TERM 信号 if pgrep -f "postgres" >/dev/null; then warning " PostgreSQL 仍在运行,发送 TERM 信号..." pkill -TERM postgres sleep 5 fi # 方法3: 如果仍在运行,检查特定进程 if pgrep -f "postgres" >/dev/null; then warning " PostgreSQL 仍在运行,检查具体进程..." # 列出所有 postgres 进程 pgrep -f "postgres" | while read pid; do ps -p $pid -o command= | grep -v "grep" && echo " 停止进程 $pid" kill -TERM $pid 2>/dev/null || true done sleep 3 fi # 方法4: 强制停止 if pgrep -f "postgres" >/dev/null; then warning " PostgreSQL 仍在运行,强制停止..." pkill -KILL postgres fi success " PostgreSQL 已停止" fi # MongoDB - 改进的停止方法 if pgrep -f "mongod" >/dev/null; then log " 停止 MongoDB..." # 方法1: 使用 mongod --shutdown (需要 sudo) echo "accusys" | sudo -S mongod --dbpath /opt/homebrew/var/mongodb --shutdown 2>/dev/null || true sleep 10 # 增加等待时间 # 方法2: 如果仍在运行,发送 TERM 信号 if pgrep -f "mongod" >/dev/null; then warning " MongoDB 仍在运行,发送 TERM 信号..." echo "accusys" | sudo -S pkill -TERM mongod 2>/dev/null || true sleep 5 fi # 方法3: 强制停止 if pgrep -f "mongod" >/dev/null; then warning " MongoDB 仍在运行,强制停止..." echo "accusys" | sudo -S pkill -KILL mongod 2>/dev/null || true fi success " MongoDB 已停止" fi # MariaDB if pgrep -f "mariadbd" >/dev/null; then log " 停止 MariaDB..." mysqladmin -u root shutdown 2>/dev/null || true sleep 5 if pgrep -f "mariadbd" >/dev/null; then pkill -TERM mariadbd sleep 3 fi success " MariaDB 已停止" fi # Qdrant if pgrep -f "qdrant" >/dev/null; then log " 停止 Qdrant..." pkill -TERM qdrant sleep 3 success " Qdrant 已停止" fi # 步骤7: 最终清理和验证 log "步骤7: 最终清理和验证..." # 等待所有进程停止 sleep 5 # 检查剩余进程 log "检查剩余进程..." services=( "momentry server:momentry" "redis-server:redis" "postgres:postgresql" "mongod:mongodb" "mariadbd:mariadb" "qdrant:qdrant" "gitea web:gitea" "sftpgo serve:sftpgo" "caddy:caddy" "php-fpm:php-fpm" "n8n:n8n" "ollama:ollama" "asr_processor:asr" "cut_processor:cut" ) all_stopped=true remaining_count=0 for service in "${services[@]}"; do process="${service%:*}" name="${service#*:}" if pgrep -f "$process" >/dev/null; then error "$name 仍在运行" all_stopped=false remaining_count=$((remaining_count + 1)) else success "$name 已停止" fi done echo "" echo "================================================" if $all_stopped; then success "✅ 所有服务已优雅停止!" echo "" echo "改进的关机机制测试成功!" echo "所有服务已正确停止。" else warning "⚠️ 仍有 $remaining_count 个服务在运行。" echo "" echo "改进建议:" echo "1. 增加服务特定的停止超时时间" echo "2. 添加更详细的进程检查" echo "3. 考虑使用服务管理工具 (systemctl/launchctl)" fi # 保存改进报告 REPORT_FILE="/tmp/improved_shutdown_report_$(date +%s).txt" { echo "改进的服务关机机制测试报告" echo "时间: $(date)" echo "========================================" echo "测试结果: $([ $all_stopped = true ] && echo "成功" || echo "部分成功")" echo "剩余进程: $remaining_count" echo "" echo "改进措施:" echo "1. 增加停止等待时间" echo "2. 多阶段停止策略 (优雅 → TERM → KILL)" echo "3. 更好的进程检查" echo "4. sudo 权限处理改进" } >"$REPORT_FILE" log "详细报告保存到: $REPORT_FILE" echo "================================================" exit 0