webman reload 命令部分生效:仅重载 Worker 进程中动态加载的代码(如 onMessage 内 require 的文件),不重载静态配置、OPcache 缓存、类定义、const、define() 及预加载逻辑;需查 PID 变化或日志确认真实生效。

webman reload 命令到底有没有生效?
大多数时候没生效,不是命令错了,而是你没看清它“重载什么、不重载什么”。php start.php reload 本质是向主进程发 SIGUSR1,触发 Worker 进程逐个退出+重启,但仅限于 Worker 进程内动态加载的 PHP 代码——比如在 onMessage 回调里用 require 引入的业务文件。
以下情况 reload 完全无效:
-
onWorkerStart里一次性require或写死的逻辑(如$config = ['host' => 'old'];),reload 后仍是旧值 - OPcache 开启且
opcache.enable_cli=1,CLI 模式下字节码不会自动失效,新代码根本没执行 - 类定义、
const、define()、静态属性等已加载进内存的符号,reload 不会重新解析
验证是否生效,别只信终端输出的 “Reload success”:查 php start.php status 输出的 Worker PID 是否变化;或翻 runtime/log/worker.log,看是否有新 worker#0 started 记录。
为什么改了代码 reload 后接口还是返回旧结果?
典型现象:修改了 app/controller/Api.php 里的 echo 'v2';,执行 php start.php reload,curl 却仍返回 v1。这不是 Webman bug,是加载路径没对上。
立即学习“PHP免费学习笔记(深入)”;
排查按顺序来:
- 确认控制器是否在
onMessage或onRequest中被动态 require —— Webman 默认使用 Composer 自动加载,而 autoloader 加载的类不受 reload 影响 - 临时禁用 OPcache 测试:
php -d opcache.enable_cli=0 start.php reload;长期方案是设opcache.revalidate_freq=0或关掉opcache.enable_cli - 检查是否用了
webman\support\Bootstrap预加载机制,或config/bootstrap.php里提前引入了类 —— 这些都在 Worker 初始化阶段完成,reload 不会重跑
Monitor 进程触发的自动重启真的平滑吗?
Webman 的 Monitor 进程(默认监听 app/ 和 config/ 目录)在检测到 PHP 文件变更时,会调用 posix_kill($pid, SIGINT) 发送中断信号。这看起来像优雅退出,但实际不是标准的 reload 流程。
关键差异点:
-
Monitor触发的是SIGINT,等效于手动 Ctrl+C,主进程会立即终止所有 Worker,不等待当前请求完成 - 它不走
SIGUSR1+ 逐个替换 Worker 的路径,因此存在极小概率丢失正在处理的 HTTP 请求(压测中约万分之一失败率) - 内存监控超限时同样用
SIGINT,和文件变更一样,不是真正平滑
生产环境务必禁用 Monitor 的自动重启('enable_file_monitor'=>false),改用人工 php start.php reload 控制节奏。
哪些变更必须用 restart 而非 reload?
php start.php restart 是先 stop 再 start,有秒级中断,但它能重建整个进程树,覆盖 reload 无能为力的场景:
- 修改了
config/process.php中的count、listen、user等 Worker 构造参数 - 调整了
config/bootstrap.php里影响全局初始化的逻辑(如自定义 autoloader 注册时机) - 更新了 Composer 依赖,涉及类名/命名空间变动,或需要重新生成 autoload_classmap.php
- 更换了 SSL 证书、修改 Nginx 反向代理配置后需同步重启 Webman 的 HTTPS Worker
注意:restart 命令本身不接受 -d 参数;守护进程模式由首次 start -d 决定,后续 restart 会沿用原模式。



















