Workerman服务需通过reload实现不中断长连接的平滑更新:先确认服务运行态,执行php start.php reload触发SIGUSR1信号,新旧子进程交替;验证需查PID变化、日志时间戳及接口响应;禁用OPcache、动态加载业务逻辑、按需引入文件可避免失效;修改主进程配置或PHP内存固化内容须restart。

Workerman服务需要更新业务逻辑但又不能中断任何长连接,比如WebSocket聊天室正在传输消息、IoT设备持续上报数据、游戏客户端保持心跳——此时直接stop再start会导致所有连接瞬间断开,必须用真正平滑的方式完成代码切换。
确认当前运行状态
执行php start.php status,检查输出中是否显示“Worker process status”及对应PID列表。若提示“No worker process running”,说明服务未启动,reload命令将无效。
【必须确保服务已处于运行态】,否则reload无目标进程可发信号。
执行标准 reload 命令
在项目根目录下运行:php start.php reload。
这条命令会向主进程发送SIGUSR1信号,触发子进程逐个替换:老进程处理完当前onMessage/onClose回调后退出,新进程立即加载最新PHP文件接单。
终端显示“Reload success”仅表示信号已发出,不等于代码已生效。
验证 reload 是否真实生效
第一步:再次运行php start.php status,对比前后Worker PID列表——至少有一个worker#编号对应的PID发生变化,说明子进程已被替换。
第二步:查看runtime/log/worker.log末尾是否有类似worker#0 started的新记录,时间戳应为reload执行后。
第三步:用curl或Postman请求一个明确修改过的接口(例如返回字符串从'v1'改为'v2'),确认响应内容已更新。
避免 reload 失效的三个关键操作
方法一:禁用 CLI 模式下的 OPcache 缓存
在onWorkerStart回调开头添加:opcache_reset();。否则即使文件已改,PHP仍执行旧字节码。
方法二:把业务逻辑移到 onMessage 中动态加载
不要在Worker初始化阶段写死逻辑,例如:
✘ 错误写法:$worker->onWorkerStart = function() { $config = ['api' => 'old']; };
✔ 正确写法:$worker->onMessage = function($connection, $data) { require 'app/logic/v2.php'; };
方法三:绕过 Composer 自动加载固化问题
若使用Webman等框架,避免在bootstrap.php中一次性加载全部Controller类;改用include_once或require在onMessage内按需载入具体文件。
什么情况下 reload 不起作用?
改了start.php本身、监听端口、$worker->count、SSL配置参数——这些影响主进程初始化的变更,reload完全不读取,必须用php start.php restart。
修改了类定义(如新增public function)、define()常量、静态属性、全局变量——这些在PHP进程内存中已固化,reload不会重载,需restart或手动清理环境。
使用GatewayWorker架构时,只对BusinessWorker执行reload;Gateway进程默认$gateway->reloadable = false,连接由它维持,业务更新不影响在线状态。

















