thinkphp queue:work 不自动重载代码是因为其常驻进程只在启动时加载类,php 不支持运行时替换类;修改消费者代码后需手动重启进程,推荐使用 php think queue:restart(需 v6.1+ 且启用 --daemon)或 supervisor 重启,避免轮询加载等错误方式。

php think queue:work)启动后不会自动感知文件变更,改了消费者代码(比如 app\common\queue\TestQueue.php)必须手动重启进程才能生效——这是默认行为,不是 bug。
为什么 queue:work 不重载代码?
因为 queue:work 是基于 Laravel/ThinkPHP 的常驻命令行进程,它只在启动时加载一次类和配置,后续所有任务都在同一个 PHP 进程内复用已加载的类定义。PHP 本身不支持运行时替换类(除非用 eval 或 runkit,但 ThinkPHP 不用、也不该用)。
修改 TestQueue.php 后如何让新逻辑立即执行?
不能靠“清缓存”或“重载语言包”那一套,得从进程生命周期入手。以下方法按推荐顺序排列:
- 开发期最简单:每次改完就
kill -SIGUSR2 {pid}(如果启用了热重载信号),或直接php think queue:restart触发平滑重启——前提是你的 ThinkPHP 版本 ≥ v6.1 且启用了--daemon模式 - 若没启用 daemon 模式,就只能
kill当前进程再php think queue:work --daemon重新拉起;注意加--daemon才支持queue:restart - 别写
while(true)自己轮询 +include类文件来模拟重载——这会破坏 ThinkPHP 的容器绑定、DB 连接复用、日志上下文等,极易引发内存泄漏或事务错乱 - 如果你用的是 Supervisor 管理队列进程,改完代码后要
supervisorctl restart thinkphp-queue,而不是只 reload 配置
想彻底避免手动重启?换架构思路
常驻进程 + 热重载本质是妥协方案。真正解耦、可灰度、易调试的方式是:
- 把业务逻辑抽成独立服务(HTTP 或 gRPC),
TestQueue只负责接收消息、校验、转发,不包含核心处理代码;这样改逻辑只需重启那个小服务,不影响队列主进程 - 用
queue:listen替代queue:work(ThinkPHP v5.x 支持):它每次取一个任务都 fork 新进程,天然加载最新代码,但性能开销略大,适合低频或调试场景 - 上线后禁止直接改生产环境代码;全部走 CI/CD 构建镜像 + 滚动更新,用容器化隔离代码版本
容易被忽略的关键点
很多人以为 Lang::clear() 或 opcache_reset() 能让队列消费者重载类——不行。OPcache 清除只影响 require/include 的脚本,而 queue:work 已经把类加载进内存并实例化了对象,静态属性、单例、数据库连接全还在。真正起作用的只有进程级重启或代码分层隔离。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











