reload 命令生效,但仅替换 Worker 子进程并重载动态加载的代码;静态配置、OPcache 缓存、全局变量、类定义等不受影响,需 restart 或手动清理缓存。

reload 命令到底有没有生效?先看三个信号级事实
Workerman 的 php start.php reload 不是“重新跑一遍脚本”,而是主进程收到 SIGUSR1 后,**逐个替换 Worker 子进程**:老进程处理完当前请求再退出,新进程加载最新 PHP 代码立即上岗。所以它天然不中断连接,但前提是——你的业务逻辑得“配合”这个机制。
- 只有
onWorkerStart、onMessage、onConnect等回调里动态加载的代码(比如require './logic.php')才会被 reload 刷新;写死在 Worker 初始化里的变量或配置,reload 后还是旧值 - 如果用了 OPcache(尤其是
opcache.enable_cli=1),PHP CLI 模式下缓存不会自动失效,reload 后仍执行旧字节码——这是线上 reload 失效最常见原因 -
reload不会重启主进程,也不会重载全局常量、define()或class_exists()已加载的类定义;类变更必须重启整个服务
reload 命令怎么用?参数和场景要分清
命令本身很简单,但不同参数对应完全不同的行为:
-
php start.php reload:标准平滑重启,推荐用于日常代码更新(如修改了onMessage里的业务逻辑) -
php start.php reload -d:无效写法 ——reload本身不接受-d,守护进程模式由启动时决定,reload 只作用于已运行的进程组 -
php start.php restart:先stop再start,有秒级中断,适合改了 Worker 构造参数(如监听端口、$worker->count)等必须重建主进程的场景 - 调试时别只看终端输出是否显示 “Reload success”,要用
php start.php status确认 Worker 进程 PID 是否已变化,或查日志里是否有worker#0 started新记录
为什么 reload 后接口返回还是旧结果?排查三步走
现象很典型:改了 onMessage 里的 echo 内容,执行 reload,curl 测试却没变。这不是 Workerman 的 bug,而是加载路径没走对。
- 检查你是否在回调里用了
require/include动态加载业务文件 —— 如果是直接写死逻辑(比如echo 'v1';),reload 根本不触发重解析,因为 PHP 进程内存里代码段早编译好了 - 确认没开 OPcache 缓存 CLI:临时禁用可加
php -d opcache.enable_cli=0 start.php reload,长期方案是关掉opcache.enable_cli或设opcache.revalidate_freq=0 - ThinkPHP/Laravel 等框架集成时,别把配置一次性全塞进
onWorkerStart;应像这样在onMessage中按需C(load_config(...)),否则 reload 只刷新回调壳子,里面还是旧配置
reload 不是万能的,哪些情况它压根不碰
它只管 Worker 子进程的“生命周期替换”,其他一切都不动。这意味着:
- 主进程里定义的全局变量(如
$config = [...]在start.php顶层)、静态属性、单例对象状态,reload 后保持原样 -
Worker::$stdoutFile、Worker::$pidFile等配置项只在启动时读取一次,reload 不会重读 —— 改了这些必须restart - 使用
Timer::add()启动的定时器,如果是在onWorkerStart里注册的,reload 后新进程会重新注册;但如果定时器逻辑依赖外部状态(如文件、数据库),而该状态没随 reload 更新,行为就会不一致
真正需要 reload 生效的地方,永远是“每次请求都重新进入的回调 + 动态加载”。别的,别指望它管。










