第一排查点是确认队列监听进程是否存活:执行ps aux | grep 'queue:work'或supervisorctl status laravel-worker检查进程状态,避免--once或未加--daemon导致无法持续消费。

确认队列监听进程是否存活
任务积压的第一排查点是消费者进程有没有真正在跑。Laravel 不会自动启动 worker,全靠 php artisan queue:work 或 queue:listen 命令维持。如果进程意外退出或根本没启动,所有新任务就只能堆在队列里干等。
Linux/macOS 下直接执行:ps aux | grep 'queue:work'
看输出中是否有带 --daemon 或长期运行状态的进程。若用 Supervisor 管理,运行:supervisorctl status laravel-worker
确保状态为 RUNNING,不是 STOPPED 或 STARTING。
注意两种常见陷阱:
- 使用 --once 参数时,worker 执行完一个任务就退出,无法持续消费
- 没加 --daemon 时,每次处理完任务都会重建进程,开销大且易中断
检查队列底层存储是否真有积压
光看进程在跑还不够,得确认任务确实卡在“待消费”状态,而不是已被取走但卡在执行中。
Redis 驱动下,连上 Redis 执行:redis-cli llen queues:default
(队列名以 QUEUE_CONNECTION 和 QUEUE_NAME 配置为准,如 queues:emails)
数值持续上涨,说明入队快、消费慢或消费停滞。
Database 驱动下,查 jobs 表:SELECT COUNT(*) FROM jobs WHERE reserved_at IS NULL AND attempts <br>
这条语句只统计“还没被任何 worker 拿走”的任务——这才是真正意义上的积压。
如果用 Horizon,直接打开 /horizon 页面,首页就能看到各队列的 pending 数、active worker 数、最近失败数,一目了然。
定位失败任务与重试配置是否生效
很多积压其实不是消费慢,而是任务反复失败又没重试,结果越堆越多。要分两步看:
先查失败表:php artisan queue:failed
或直查 failed_jobs 表的 exception 字段,看报错是不是连接超时、模型找不到、第三方 API 拒绝这类高频问题。
再核对重试逻辑是否启用:
- 启动 worker 时有没有加 --tries=3
- 任务类里有没有定义 public $tries = 3;
- 如果两者都没设,任务失败后**直接进 failed_jobs,绝不重试**
还要留意重试间隔设置:public $backoff = [1, 5, 30];
表示第 1 次失败后等 1 秒重试,第 2 次等 5 秒,第 3 次等 30 秒。如果数组太短,后续失败都按最后一个值延时,容易造成“看起来像卡住”。
验证任务能否被正常反序列化与执行
即使进程在跑、队列有数据、重试也开了,任务仍可能因序列化问题静默失败——比如模型用了未加载的 trait、闭包被序列化、或 PHP 版本升级后对象结构变化。
可在任务的 handle() 开头加一行日志:\Log::info('Job started', ['job_id' => $this->job->getJobId() ?? 'unknown']);
如果日志里完全没这条记录,说明任务压根没进入执行阶段,大概率卡在反序列化或中间件拦截。
常见风险点:
- 任务构造函数传了不可序列化的对象(如 Request、Response、数据库连接)
- 使用了 SerializesModels 但模型关联了大量未预加载的数据,反序列化时触发 N+1 查询超时
- Redis 驱动下,serialize 配置误设为 igbinary 但扩展未安装
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











