workerman4的reload不中断连接,因其主进程仅发sigusr1信号协调子进程轮换,老进程处理完当前请求并拒绝新连接后退出,新进程立即加载最新代码接单,实现平滑过渡。

Workerman4 的 reload 能做到不中断已有连接,核心在于它不杀进程、不关监听套接字,而是用“新老交替”的方式完成代码更新。
主进程只发信号,不终止服务
执行 php start.php reload 时,终端向 Workerman 主进程发送的是 SIGUSR1 信号。主进程本身不退出,也不关闭监听端口(如 TCP/WS 端口),只是开始协调子进程轮换。这意味着:客户端的 TCP 连接始终被某个 Worker 子进程持有,不会因 reload 被强制断开。
子进程逐个优雅退出
每个旧 Worker 子进程收到通知后,并非立刻死亡,而是按以下顺序行动:
- 继续处理当前正在执行的 onMessage、onClose 或 onWorkerStop 回调(哪怕耗时几秒)
- 立即停止接受新连接(监听 socket 仍开着,但不再 accept)
- 等待所有已建立连接自然关闭(比如客户端主动断开、心跳超时、或消息处理完毕)
- 所有连接清理完成后,进程自行退出
新进程加载新代码立即上岗
主进程在旧进程退出的同时,就 fork 出一个新 Worker 子进程。这个新进程:
- 会重新执行启动脚本(如 start.php),加载最新 PHP 文件
- 重新初始化 onWorkerStart 中的逻辑(比如数据库连接、Redis 客户端、配置读取)
- 立刻开始 accept 新连接、处理新来的 onMessage 请求
老进程和新进程在一段时间内共存,流量平滑过渡——用户感知不到切换。
关键前提:业务逻辑必须可重载
reload 只对运行时动态加载的部分生效。真正起作用的写法包括:
- 在 onMessage 回调里用 require 或 include 引入业务文件
- 路由分发逻辑写在回调中,每次请求都重新判断
- 避免在 new Worker() 后直接赋值变量、new 单例、或使用 static 缓存状态
- 确保 OPcache 不锁住旧代码(CLI 模式下建议关闭 opcache.enable_cli=0 或手动 opcache_reset())











