think-queue不是装完自动运行,必须手动启动消费者进程;php think queue:listen仅前台阻塞监听、适合开发调试,生产环境需用php think queue:work配合Supervisor等进程管理工具保活。

think-queue 不是装完就能自动跑的,它必须手动启动消费者进程来监听和执行任务。默认情况下,所有推入队列的任务都处于“待处理”状态,不会自己运行。
为什么 php think queue:listen 启动后没反应?
这是最常见误解:以为命令执行完就“生效了”,其实它只是前台阻塞式监听——终端窗口必须保持打开,进程不能被 Ctrl+C 或 shell 退出中断。
-
php think queue:listen是开发调试用的,只监听一个队列(默认default),不支持多进程、无失败重试兜底 - 一旦终端关闭或 SSH 断连,进程立即终止,任务积压在 Redis/DB 里但没人处理
- 生产环境必须用
php think queue:work+ 进程管理工具(如 supervisor)保活 - 如果配置了
'default' => 'sync',那根本不会进队列,而是直接同步执行——此时queue:listen命令压根不生效
queue:work 和 queue:listen 到底该用哪个?
看场景选,不是版本高低问题:
-
queue:listen:适合本地开发快速验证逻辑,会自动重启 worker(比如改了代码后不用手动 stop/start),但每次只取一个任务,吞吐低 -
queue:work:生产首选,支持--daemon模式(常驻内存)、--once单次执行、--sleep空闲休眠、--max-jobs限制总执行数,更可控 - 注意:
queue:work --daemon在 ThinkPHP 6+ 中已被弃用,改用queue:work不加参数即可常驻(底层已自动优化) - 如果你发现
queue:work启动后立刻退出,大概率是任务类fire()方法抛了未捕获异常,导致 worker 进程崩溃
Redis 驱动下任务不消费?先检查这三处
Redis 是最常用驱动,但配置错一处就卡死:
-
config/queue.php里'default' => 'redis'和'connections.redis.type' => 'redis'必须一致;若写成'type' => 'Redis'(首字母大写)会静默失败 -
'host'和'port'要跟config/cache.php中 Redis 配置完全一致,否则连接的是两个不同实例(尤其 Docker 环境容易 host 写成localhost) - Redis 的
select数据库要空闲,比如设为1,但实际 Redis 没启用 db1(redis.conf中databases 16才支持 db1),会导致BRPOP阻塞超时却无报错
任务类 fire() 执行完不自动删除?
这不是 bug,是设计行为:只有成功执行且没抛异常,think-queue 才从队列中移除该任务。一旦 fire() 抛出异常,任务会被放回队列尾部(可配置重试次数)。
立即学习“PHP免费学习笔记(深入)”;
- 务必在
fire()内部用try/catch包住核心逻辑,避免第三方接口超时直接崩掉 worker - 调用
$job->delete()可手动删除(适合“成功但需延迟清理”的场景);调用$job->release($delay)可延后重试 - Redis 驱动下,任务原始数据存在
queues:defaultlist 中,失败任务会进入queues:default:failed—— 这个 key 不会自动清理,积多了影响性能



















