think-queue默认使用sync驱动,任务同步执行而非异步;必须将config/queue.php中'default'改为redis等异步驱动,显式配置host、port、database和retry_after,并用supervisor守护php think queue:work命令,否则任务不会真正异步执行。

PHP 8.5 本身不内置队列功能,异步队列依赖框架或扩展实现。ThinkPHP 8.1.4 + think-queue v3.x 是目前对 PHP 8.5 支持最完善、配置最清晰的组合之一。关键不是“PHP 版本配队列”,而是选对兼容的框架版本和驱动,并避开默认陷阱。
确认默认不是异步:sync 驱动必须改掉
think-queue 安装后默认使用 sync 驱动——任务看似入队,实则立即同步执行,无延迟、无并发、无失败记录,也根本不会走 Redis 或数据库。这是 90% 的人“push 了但没反应”的根本原因。
- 打开
config/queue.php,检查'default' => 'sync'—— 这行必须改成'redis'(或其他你选用的异步驱动) - sync 模式下,
$job->delete()和$job->release()全部无效,因为没持久化过程 - 加
sleep(5)测试:HTTP 响应仍秒回 → 还在 sync;卡 5 秒才返回 → 是真同步执行(说明你还没切到异步)
Redis 驱动要填全三项,缺一不可
只写 'driver' => 'redis' 不够。ThinkPHP 8.0+ 的 think-queue v3.x 不读取 Predis 全局配置,必须在 connections.redis 下显式声明:
-
host 和 port:不能省略,即使本地也要写
'host' => '127.0.0.1', 'port' => 6379 -
database:Redis 多 DB 场景下必须指定,如
'database' => 4('select'参数已废弃) -
retry_after:最关键!它不是重试间隔,而是单个任务最长允许执行时间(单位:秒)。若发短信实际耗时 75 秒,这里设成 60 就会触发重复投递。建议设为预估最大耗时 × 1.5,例如
'retry_after' => 120
消费者进程不能用 --daemon,必须交由 supervisor 管理
php think queue:work redis --daemon 看似省事,实则危险:CLI 进程长期驻留会累积内存泄漏,几小时后可能 OOM 崩溃。
- 正确做法:去掉
--daemon,运行php think queue:work redis --tries=3 --delay=10 - 用 supervisor 守护该命令,配置
autostart=true、autorestart=true、stopwaitsecs=10 - 每次任务执行完进程退出,supervisor 自动拉起新实例,内存干净、稳定可控
失败任务必须手动处理,Redis 默认不记日志
Database 驱动会自动建 failed_jobs 表并写入错误;Redis 驱动则完全静默——崩了你也看不到。
- 生产环境务必监听
JobFailed事件,在回调中记录$event->job和$event->exception到文件或数据库 - 或者启用
--tries=3让框架自动重试,但原始异常堆栈仍不保留 - 别指望
php think queue:failed查 Redis 失败任务——它只对 database 驱动有效
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











