File size: 7,898 Bytes
0f10134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

#!/bin/bash

# 智能分析系统管理脚本
# 功能:启动、停止、重启和监控系统服务

# 配置
APP_NAME="智能分析系统"
APP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
PYTHON_CMD="${APP_DIR}/env/bin/python"
SERVER_SCRIPT="run.py"
PID_FILE="${APP_DIR}/data/.server.pid"
LOG_FILE="${APP_DIR}/data/server.log"
MONITOR_INTERVAL=30  # 监控检查间隔(秒)

# 颜色配置
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 无颜色

# 函数:显示帮助信息
show_help() {
    echo -e "${BLUE}${APP_NAME}管理脚本${NC}"
    echo "使用方法: $0 [命令]"
    echo ""
    echo "命令:"
    echo "  start       启动服务"
    echo "  stop        停止服务"
    echo "  restart     重启服务"
    echo "  status      查看服务状态"
    echo "  monitor     以守护进程方式监控服务"
    echo "  logs        查看日志"
    echo "  help        显示此帮助信息"
}

# 函数:检查前置条件
check_prerequisites() {
    # 检查Python是否已安装
    if ! command -v $PYTHON_CMD &> /dev/null; then
        echo -e "${RED}错误: 未找到Python命令。请确保Python已安装且在PATH中。${NC}"
        exit 1
    fi

    # 检查server脚本是否存在
    if [ ! -f "${APP_DIR}/${SERVER_SCRIPT}" ]; then
        echo -e "${RED}错误: 未找到服务器脚本 ${SERVER_SCRIPT}${NC}"
        echo -e "${YELLOW}当前目录: $(pwd)${NC}"
        exit 1
    fi

    # 确保日志和PID目录存在
    local data_dir=$(dirname "$PID_FILE")
    if [ ! -d "$data_dir" ]; then
        echo -e "${YELLOW}数据目录不存在,正在创建: ${data_dir}${NC}"
        mkdir -p "$data_dir"
    fi
}

# 函数:获取进程ID
get_pid() {
    if [ -f "$PID_FILE" ]; then
        local pid=$(cat "$PID_FILE")
        if ps -p $pid > /dev/null; then
            echo $pid
            return 0
        fi
    fi
    # 尝试通过进程名查找
    local pid=$(pgrep -f "python.*${SERVER_SCRIPT}" 2>/dev/null)
    if [ -n "$pid" ]; then
        echo $pid
        return 0
    fi
    echo ""
    return 1
}

# 函数:启动服务
start_server() {
    local pid=$(get_pid)
    if [ -n "$pid" ]; then
        echo -e "${YELLOW}警告: 服务已在运行 (PID: $pid)${NC}"
        return 0
    fi

    echo -e "${BLUE}正在启动${APP_NAME}...${NC}"
    cd "$APP_DIR"

    # 使用nohup在后台启动服务
    nohup $PYTHON_CMD $SERVER_SCRIPT > "$LOG_FILE" 2>&1 &
    local new_pid=$!

    # 保存PID到文件
    echo $new_pid > "$PID_FILE"

    # 等待几秒检查服务是否成功启动
    sleep 3
    if ps -p $new_pid > /dev/null; then
        echo -e "${GREEN}${APP_NAME}已成功启动 (PID: $new_pid)${NC}"
        return 0
    else
        echo -e "${RED}启动${APP_NAME}失败。查看日志获取更多信息: ${LOG_FILE}${NC}"
        return 1
    fi
}

# 函数:停止服务
stop_server() {
    local pid=$(get_pid)
    if [ -z "$pid" ]; then
        echo -e "${YELLOW}服务未运行${NC}"
        return 0
    fi

    echo -e "${BLUE}正在停止${APP_NAME} (PID: $pid)...${NC}"

    # 尝试优雅地停止服务
    kill -15 $pid

    # 等待服务停止
    local max_wait=10
    local waited=0
    while ps -p $pid > /dev/null && [ $waited -lt $max_wait ]; do
        sleep 1
        waited=$((waited + 1))
        echo -ne "${YELLOW}等待服务停止 $waited/$max_wait ${NC}\r"
    done
    echo ""

    # 如果服务仍在运行,强制停止
    if ps -p $pid > /dev/null; then
        echo -e "${YELLOW}服务未响应优雅停止请求,正在强制终止...${NC}"
        kill -9 $pid
        sleep 1
    fi

    # 检查服务是否已停止
    if ps -p $pid > /dev/null; then
        echo -e "${RED}无法停止服务 (PID: $pid)${NC}"
        return 1
    else
        echo -e "${GREEN}服务已成功停止${NC}"
        rm -f "$PID_FILE"
        return 0
    fi
}

# 函数:重启服务
restart_server() {
    echo -e "${BLUE}正在重启${APP_NAME}...${NC}"
    stop_server
    sleep 2
    start_server
}

# 函数:检查服务状态
check_status() {
    local pid=$(get_pid)
    if [ -n "$pid" ]; then
        local uptime=$(ps -o etime= -p $pid)
        local mem=$(ps -o %mem= -p $pid)
        local cpu=$(ps -o %cpu= -p $pid)

        echo -e "${GREEN}${APP_NAME}正在运行${NC}"
        echo -e "  PID:     ${BLUE}$pid${NC}"
        echo -e "  运行时间: ${BLUE}$uptime${NC}"
        echo -e "  内存使用: ${BLUE}$mem%${NC}"
        echo -e "  CPU使用:  ${BLUE}$cpu%${NC}"
        echo -e "  日志文件: ${BLUE}$LOG_FILE${NC}"
        return 0
    else
        echo -e "${YELLOW}${APP_NAME}未运行${NC}"
        return 1
    fi
}

# 函数:监控服务
monitor_server() {
    echo -e "${BLUE}开始监控${APP_NAME}...${NC}"
    echo -e "${BLUE}监控日志将写入: ${LOG_FILE}.monitor${NC}"
    echo -e "${YELLOW}按 Ctrl+C 停止监控${NC}"

    # 在后台启动监控
    (
        while true; do
            local pid=$(get_pid)
            local timestamp=$(date '+%Y-%m-%d %H:%M:%S')

            if [ -z "$pid" ]; then
                echo "$timestamp - 服务未运行,正在重启..." >> "${LOG_FILE}.monitor"
                cd "$APP_DIR"
                $PYTHON_CMD $SERVER_SCRIPT >> "$LOG_FILE" 2>&1 &
                local new_pid=$!
                echo $new_pid > "$PID_FILE"
                echo "$timestamp - 服务已重启 (PID: $new_pid)" >> "${LOG_FILE}.monitor"
            else
                # 检查服务是否响应 (可以通过访问服务API实现)
                local is_responsive=true

                # 这里可以添加额外的健康检查逻辑
                # 例如:使用curl检查API是否响应
                # if ! curl -s http://localhost:8888/health > /dev/null; then
                #     is_responsive=false
                # fi

                if [ "$is_responsive" = false ]; then
                    echo "$timestamp - 服务无响应,正在重启..." >> "${LOG_FILE}.monitor"
                    kill -9 $pid
                    sleep 2
                    cd "$APP_DIR"
                    $PYTHON_CMD $SERVER_SCRIPT >> "$LOG_FILE" 2>&1 &
                    local new_pid=$!
                    echo $new_pid > "$PID_FILE"
                    echo "$timestamp - 服务已重启 (PID: $new_pid)" >> "${LOG_FILE}.monitor"
                fi
            fi

            sleep $MONITOR_INTERVAL
        done
    ) &

    # 保存监控进程PID
    MONITOR_PID=$!
    echo $MONITOR_PID > "${APP_DIR}/.monitor.pid"
    echo -e "${GREEN}监控进程已启动 (PID: $MONITOR_PID)${NC}"

    # 捕获Ctrl+C以停止监控
    trap 'kill $MONITOR_PID; echo -e "${YELLOW}监控已停止${NC}"; rm -f "${APP_DIR}/.monitor.pid"' INT

    # 等待监控进程
    wait $MONITOR_PID
}

# 函数:查看日志
view_logs() {
    if [ ! -f "$LOG_FILE" ]; then
        echo -e "${YELLOW}日志文件不存在: ${LOG_FILE}${NC}"
        return 1
    fi

    echo -e "${BLUE}显示最新的日志内容 (按Ctrl+C退出)${NC}"
    tail -f "$LOG_FILE"
}

# 主函数
main() {
    check_prerequisites

    local command=${1:-"help"}

    case $command in
        start)
            start_server
            ;;
        stop)
            stop_server
            ;;
        restart)
            restart_server
            ;;
        status)
            check_status
            ;;
        monitor)
            monitor_server
            ;;
        logs)
            view_logs
            ;;
        *)
            show_help
            ;;
    esac
}

# 执行主函数
main "$@"