守护模式更新代码要到服务器上操作,如果开发人员没有服务器权限就不好办。
只能退而求其次,使用Supervisor之类的不加-d运行,但这种模式有个弊端,每次更新代码都会短暂502,好像还没好的办法解决(需要多套程序负载均衡)。
问了AI,可以定时检测目录下reload、restart两个文件,有就执行相关命令。
试了下,这种方案可行。
有没有办法在框架层面实现类似的?在Master进程应该能做到吧
#!/bin/bash
# ===================== 项目路径配置 =====================
PROJECTS=(
"/www/wwwroot/project1"
"/www/wwwroot/project2"
"/www/wwwroot/project3"
)
# ======================================================
PHP_BIN="php"
LOG_DIR="/var/log/webman_manager"
mkdir -p "$LOG_DIR"
# 每天一个日志文件
LOG_FILE="$LOG_DIR/webman_manager_$(date +%Y-%m-%d).log"
# 日志输出函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 自动清理 7 天前日志
find "$LOG_DIR" -name "webman_manager_*.log" -mtime +7 -delete
log "===== 开始检测项目 ====="
# 遍历项目
for PROJECT in "${PROJECTS[@]}"; do
if [ ! -d "$PROJECT" ]; then
log "项目不存在,跳过:$PROJECT"
continue
fi
if [ ! -f "$PROJECT/start.php" ]; then
log "非 Webman 项目,跳过:$PROJECT"
continue
fi
# ==================== reload 平滑重启 ====================
if [ -f "$PROJECT/reload" ]; then
log "检测到 reload,执行平滑重启:$PROJECT"
# 执行并把输出 全部写入日志
cd "$PROJECT"
$PHP_BIN start.php reload -g >> "$LOG_FILE" 2>&1
rm -f "$PROJECT/reload"
log "reload 执行完成,文件已删除"
fi
# ==================== restart 强制重启 ====================
if [ -f "$PROJECT/restart" ]; then
log "检测到 restart,执行强制重启:$PROJECT"
# 执行并把输出 全部写入日志
cd "$PROJECT"
$PHP_BIN start.php restart -d >> "$LOG_FILE" 2>&1
rm -f "$PROJECT/restart"
log "restart 执行完成,文件已删除"
fi
done
log "===== 本轮检测完成 ====="
这里提几个坑,文档里面没有详细说明,不翻代码查资料就搞不明白。
1、-d 守护模式时,重启restart命令也必须带 -d
2、realod -g 与upstream 里面的 keepalive 10240 貌似冲突(AI说的)
stop_timeout设为30,仍然感觉一些绝对不可能耗时那么久的接口被强杀。
我猜测可能是某些接口确实耗时比较长,比如定时任务、还有一个生成个人二维码的要下载远程图片。
因为开启协程,所以一个worker里面会同时有多个请求,如果其中一个协程耗时比较长,那这个worker就一直无法关闭。
在这期间还仍然开启其他协程继续接收请求,直到stop_timeout超时。所以给人的错觉是,有些接口明显是不可能耗时那么久的,还是被强杀了。
解决方法当然是区分快慢接口,把耗时就的放在单独一个端口:https://www.workerman.net/doc/webman/others/task.html
你可以在gitea或github的webhook针对分支设置回调勾子,请求你的项目地址,在接口接收到合并请求或master、product分支推送的操作类型时,推送队列消费执行sehll命令重启服务。
这样可以实现服务随代码变更自动重启
可以把热更新打开呀,webman自带的功能
已经说了呀,502问题。访问量大的时候,刚好你更新代码的时候有人访问,就报网络错误
别说用户,就是我自己都经常遇到上传了代码,然后去访问报502。这中间有多少时间间隔,怕有1~2秒钟
我也用的热更新,用了两年多webman,没碰到过更新完502的情况
stop_timeout 是执行stop时进程如果还在处理业务就等待,如果等待时间超过stop_timeout设置的时间,则执行强制杀死进程。
你平滑重启有过度时间的
奇怪难道是我代码的问题,或者是与
reusePort为false有关?可以设置 'stop_timeout' => 30, // 收到stop/restart/reload信号时,等待处理完成的最大时间,超过这个时间进程未退出则强制退出
这个就有设置过10秒,上传完代码再访问接口,绝对没10秒
你这是守护模式吗?我现在换成守护模式,更新完代码再手动restart,也没遇到502了
守护进程模式,并且开启热更新
直接 docker 吧
双机热备呗;临时再启动一个节点去使用;进行切换;