任务卡在pending状态的根因是队列系统未贯通,需同步检查三要素:1.QUEUE_CONNECTION是否误配为sync(应为redis或database);2.对应基础设施是否就绪(database需jobs表、redis需连接通);3.php artisan queue:work是否真实常驻运行。

任务卡在 pending 状态,大概率不是代码写错了,而是队列根本没“通”——配置、基础设施、运行态三者缺一不可。
QUEUE_CONNECTION 是 sync 还是 redis/database?
这是最常被忽略的起点。Laravel 默认用 sync 驱动,它不走队列,而是直接同步执行任务,所以你看不到消费日志,也查不到 jobs 表里的记录,但任务状态却显示 pending(因为框架内部状态机没被触发异步流程)。
- 检查
.env:确认QUEUE_CONNECTION=redis或QUEUE_CONNECTION=database,不能是sync - 运行
php artisan tinker后执行config('queue.default'),看输出是否匹配你的预期驱动 -
sync仅适合本地调试;生产环境必须切换,否则所有“延迟”“重试”“失败处理”都失效
jobs 表或 Redis 是否已就绪?
用了 database 驱动却没建表,或用了 redis 驱动但连接不通,任务会静默堆积,不报错也不执行。
Laravel 13.2.0 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。
- 数据库驱动:运行
php artisan queue:table→php artisan migrate,确保jobs表存在且含available_at字段 - Redis 驱动:检查
.env中REDIS_HOST、REDIS_PORT、REDIS_PASSWORD是否可连(可用redis-cli -h 127.0.0.1 -p 6379 ping验证) - 哪怕只改了
QUEUE_CONNECTION,没配好底层存储,任务照样进不去队列——它连“排队资格”都没有
php artisan queue:work 是否真正在跑?
queue:work 是个前台命令,关掉终端就停。很多人执行一次后以为“启动了”,其实进程早已退出,任务永远等不到消费者。
- 临时验证:新开终端执行
php artisan queue:work --verbose,然后分发一个任务,看控制台是否立刻打印 “Processing…” - 生产环境必须用
supervisor管理,确保常驻、崩溃自动重启 - 别依赖
nohup php artisan queue:work &,它无法处理信号、不记录 stdout/stderr、异常退出无感知 - 注意:该命令默认不监听
delay任务,如需支持延迟,请加--sleep=3参数提升轮询精度
failed_jobs 表里有没有记录?
如果任务曾被拉取但执行失败,又没配置失败处理,它可能已沉底。此时 pending 是假象——实际是上一轮失败后未重试,新任务又被压入,造成“积压错觉”。
- 先运行
php artisan queue:failed,看是否有 ID 列出 - 有记录就说明工作器至少运行过,问题在业务逻辑或依赖(比如邮件配置错误、API 认证失效)
- 查
storage/logs/laravel.log,搜索App\Jobs\YourJobName或failed,找堆栈里第一个非 Laravel 框架层的文件和行号 - 失败任务不会自动重试,除非你手动执行
php artisan queue:retry all或修复后重试单个
真正卡住的地方,往往不在 Job 类本身,而在队列系统最外层的三道门:驱动配置、存储就绪、进程存活。漏掉任意一环,任务就停在 pending —— 它甚至没机会走到你的 handle() 方法里。

















