查 Failed Jobs 应用 DB::table('failed_jobs'),对应模型是 Illuminate\Queue\Failed\FailedJob 但不可直接实例化;重点字段为 exception、payload 和 failed_at。
查 Failed Jobs 用哪个 Eloquent 模型?
直接查 failed_jobs 表,对应模型是 illuminate\queue\failed\failedjob,但别手贱去 new 它——laravel 10+ 默认禁用该模型的写操作,且它不带软删除、没有常规 accessor。真要查,走 db 门最稳:
DB::table('failed_jobs')->orderByDesc('failed_at')->limit(10)->get()- 注意字段:重点看
exception(堆栈)、payload(原始任务数据)、failed_at(时间戳) - 如果用了自定义表名(比如配置了
QUEUE_FAILED_TABLE),得换掉'failed_jobs'这个字符串
exception 字段里堆栈看不懂?先过滤关键行
堆栈通常几百行,但真正有用的就三五处:最后一段报错 + 最靠近 at app/ 的那一行。常见干扰项是 vendor/ 下的框架调用,它们只是“传话的”,不是根因。
- 用
grep -A2 -B2 'app/Http/Jobs|app/Jobs|app/Services' storage/logs/laravel.log快速定位同类错误(如果日志没关) - 如果
exception里有Call to a member function xxx() on null,八成是队列任务里用了未初始化的依赖或 Eloquent 模型被序列化后反序列化失败 - 遇到
PDOException: SQLSTATE[HY000] [2002] Connection refused,说明任务执行时数据库连不上——但失败记录本身还能写进failed_jobs,因为 Laravel 先 try 再 fail
重试单个失败任务,别直接改数据库状态
手动 update failed_jobs 表的 uuid 或删记录,只会让问题更隐蔽。正确姿势是复现+重试:
- 用
php artisan queue:retry {id}重试单条({id} 是failed_jobs.id,不是 uuid) - 想看重试时实际跑什么代码?加
--pretend:php artisan queue:retry 123 --pretend,它会打印出反序列化后的任务类和 handle 方法调用链 - 如果重试报
Class xxx does not exist,说明任务类已被删或命名空间改过——Laravel 队列序列化的是类名字符串,不是实时反射
为什么重试后又失败?检查任务构造函数和 handle 里的硬依赖
队列任务不是普通类,它的生命周期跨进程。构造函数里不能做耗时操作,handle 里不能依赖容器单例或 request 上下文。
- 典型翻车点:
public function __construct(Request $request)—— Request 无法序列化,存进队列就变空对象,运行时报Trying to get property 'xxx' of non-object - 另一个坑:
$this->user = auth()->user()写在构造函数里,重试时 auth 已失效,$this->user 是 null - 安全做法:所有外部数据都通过构造参数传入,且只传 ID 或数组等可序列化类型;真实模型在
handle()里用User::find($this->userId)拉取
payload 字段里,也不会进日志,只能靠重试时加断点或 dump 对象属性来确认。

















