- Refactor start.sh to launch multiple worker processes based on CPU core count - Assign dynamic ports to each worker (base_port + offset) - Update stop.sh to gracefully handle and kill multiple worker PIDs - Implement PID file management for multi-process tracking
105 lines
2.6 KiB
Bash
Executable File
105 lines
2.6 KiB
Bash
Executable File
#!/bin/bash
|
||
# Sage Web Application Start Script
|
||
# Multi-process support based on CPU cores
|
||
|
||
set -e
|
||
|
||
# 切换到脚本所在目录
|
||
cd "$(dirname "$0")"
|
||
|
||
# 配置
|
||
WORKDIR="$(pwd)"
|
||
PYTHON="./py3/bin/python"
|
||
APP_ENTRY="app/sage.py"
|
||
PIDFILE="$WORKDIR/sage.pid"
|
||
LOGDIR="$WORKDIR/logs"
|
||
|
||
# 确保logs目录存在
|
||
mkdir -p "$LOGDIR"
|
||
|
||
# 检查Python是否存在
|
||
if [ ! -f "$PYTHON" ]; then
|
||
echo "错误: 找不到Python解释器 $PYTHON"
|
||
echo "请确保已安装虚拟环境: ./py3/bin/python"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查应用入口文件是否存在
|
||
if [ ! -f "$APP_ENTRY" ]; then
|
||
echo "错误: 找不到应用入口文件 $APP_ENTRY"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查Redis是否运行(session存储依赖)
|
||
if command -v redis-cli &> /dev/null; then
|
||
if ! redis-cli ping &> /dev/null; then
|
||
echo "Redis未运行,正在启动Redis..."
|
||
redis-server --daemonize yes
|
||
sleep 1
|
||
if redis-cli ping &> /dev/null; then
|
||
echo "Redis启动成功"
|
||
else
|
||
echo "警告: Redis启动失败,登录功能可能无法正常工作"
|
||
fi
|
||
else
|
||
echo "Redis运行正常"
|
||
fi
|
||
fi
|
||
|
||
echo "========================================="
|
||
echo "启动 Sage Web Application"
|
||
echo "工作目录: $WORKDIR"
|
||
echo "Python: $PYTHON"
|
||
echo "========================================="
|
||
|
||
# 获取 CPU 核心数,决定启动多少 Worker
|
||
WORKERS=$(nproc)
|
||
echo "检测到 ${WORKERS} 个 CPU 核心,准备启动 ${WORKERS} 个工作进程..."
|
||
|
||
# 获取基础端口
|
||
BASE_PORT=9180
|
||
if command -v python3 &> /dev/null; then
|
||
BASE_PORT=$($PYTHON -c "
|
||
import json
|
||
try:
|
||
with open('$WORKDIR/conf/config.json') as f:
|
||
config = json.load(f)
|
||
print(config.get('website', {}).get('port', 9180))
|
||
except Exception as e:
|
||
print(9180)
|
||
" 2>/dev/null || echo 9180)
|
||
fi
|
||
|
||
# 清空 PID 文件
|
||
> "$PIDFILE"
|
||
|
||
# 循环启动 Worker
|
||
for (( i=0; i<WORKERS; i++ ))
|
||
do
|
||
PORT=$((BASE_PORT + i))
|
||
LOGFILE="$LOGDIR/sage_worker_${i}.log"
|
||
|
||
echo ">>> 启动 Worker $((i+1))/${WORKERS} on port $PORT ..."
|
||
|
||
# 启动服务
|
||
nohup $PYTHON $APP_ENTRY --workdir "$WORKDIR" --port $PORT > "$LOGFILE" 2>&1 &
|
||
APP_PID=$!
|
||
|
||
# 保存 PID
|
||
echo "$APP_PID" >> "$PIDFILE"
|
||
|
||
# 短暂等待以检查是否立即崩溃
|
||
sleep 1
|
||
if kill -0 $APP_PID 2>/dev/null; then
|
||
echo " -> Worker PID: $APP_PID (成功)"
|
||
else
|
||
echo " -> 错误: Worker 启动失败,请查看 $LOGFILE"
|
||
fi
|
||
done
|
||
|
||
echo "========================================="
|
||
echo "所有服务已启动"
|
||
echo "PID 文件: $PIDFILE"
|
||
echo "访问地址: http://localhost:${BASE_PORT} (以及其他 ${WORKERS} 个端口)"
|
||
echo "========================================="
|