用途
该技能用于在编写、审查或运维 Laravel 队列与后台任务时充当检查清单。适用于:新建后台任务(php artisan make:job)、审查新增或修改任务类的 PR、在新服务器(Forge / Vapor / 裸机)上配置队列 Worker、配置 config/queue.php 或 config/horizon.php、排查卡住/循环/反复失败的任务、在 dispatch()、dispatchSync()、dispatchAfterResponse()、Bus::batch()、Bus::chain() 之间做选择、添加队列测试(Queue::fake()、Bus::fake()),以及判断是否引入 Horizon。
检测队列配置
需检查以下文件:
- config/queue.php:默认连接(QUEUE_CONNECTION 环境变量)、失败任务存储、after_commit 设置
- config/horizon.php(如有):Horizon 环境、均衡策略、Worker 数量、超时
- app/Jobs/*.php:任务类、ShouldQueue 使用、tries/backoff、failed() 方法
- app/Console/Kernel.php 或 routes/console.php:计划任务(Schedule::job(...)、withoutOverlapping)
- database/migrations/*_create_failed_jobs_table.php:失败任务存储迁移;或 config 中的 DynamoDB 驱动
- supervisor*.conf / /etc/supervisor/conf.d/:Worker 进程管理、numprocs、--max-time、stopwaitsecs
典型配置组合:小型 Laravel + MySQL 使用 database 驱动、database 失败存储、Supervisor(或 systemd);生产 Laravel + Redis 使用 redis 驱动、database(或 serverless 用 dynamodb)失败存储、Supervisor + Horizon;Laravel Vapor 使用 sqs 驱动、dynamodb 失败存储、Vapor 托管。
规则分类与优先级
- 驱动与配置(CRITICAL,前缀 config-):config-driver-choice(小型应用用 database;生产规模用 redis;Laravel Vapor 用 sqs)、config-after-commit(设置 after_commit: true,避免派发引用未提交数据库行的任务)、config-failed-storage(必须有 failed_jobs 表,Vapor 上用 DynamoDB;设置保留与清理)。
- 任务设计(CRITICAL,前缀 design-):design-shouldqueue(每个异步任务必须实现 ShouldQueue,这是第一大生产 bug)、design-pass-ids-not-models(构造函数传 ID,在 handle() 中重新获取,避免模型过期和序列化负载膨胀)、design-idempotency(支付、外部 API 和“创建资源”任务必须可安全重跑:ShouldBeUnique、幂等键、唯一数据库约束)、design-constructor-vs-handle(构造函数在派发时同步执行,handle() 在 Worker 上执行;构造函数中不得写数据库或发起 HTTP 调用)。
- 重试与失败(HIGH,前缀 retry-):retry-tries-and-backoff(同时设置:#[Backoff([1, 5, 30])] 实现指数退避;默认 3 次对瞬时故障通常不够)、retry-failed-method(实现 failed(Throwable $e) 处理永久失败:告警、退款、标记失败)、retry-transient-vs-permanent(瞬时错误用 release($delay),永久错误用 throw)、retry-fail-on-timeout(用 #[FailOnTimeout] 避免挂起任务耗尽所有尝试)。
- 扩容与 Worker(HIGH,前缀 scaling-):scaling-supervisor-config(由 Supervisor 或 systemd 管理 Worker;stopwaitsecs 大于超时;--max-time=3600 回收进程)、scaling-multi-queue-priority(为 SLA 关键任务使用 high/default/low 队列通道;--queue=high,default,low)、scaling-worker-recycling(--max-jobs 和 --max-time 应对长时间运行 Worker 的内存泄漏)。
- 批处理与链式(HIGH,前缀 bus-):bus-batch-vs-chain(Bus::batch 用于并行并可跟踪进度;Bus::chain 用于严格顺序)、bus-batch-failure-handling(容错批处理用 allowFailures();使用 then/catch/finally 回调)、bus-chunking-large-sets(1000+ 条目时通过 Bus::batch(...) 分块,而非每条目一个任务)。
- 测试与运维(MEDIUM,前缀 ops-):ops-queue-fake(测试中用 Queue::fake() / Bus::fake();assertDispatched、assertPushed、assertChained、assertBatched)、ops-schedule-queued-jobs(Schedule::job(new X)->everyMinute() 会将任务入队,配合 withoutOverlapping() 更安全)、ops-horizon-when(在 Redis 且有多个 Supervisor 时采用 Horizon;不适用于 database 队列或单 Worker 配置)。
使用方式
当用户提出“设计这个后台任务”“审计我们的队列配置”“这个任务为什么不运行”等队列相关问题时,按该技能的规则清单对照相关文件逐条检查。审计模式下按规则输出结论:PASS(模式应用正确)、FAIL(存在反模式,附 file:line 和修复建议)、N/A(不适用该代码库)。最后给出最高优先级修复清单(支付任务幂等、缺少 ShouldQueue、supervisor stopwaitsecs 过低,这些是最常见的生产隐患)。
关键模式
最小可用任务类(Laravel 13)示例代码见资料:使用 #[Backoff([1, 5, 30])]、#[FailOnTimeout]、ShouldQueue,构造函数传 orderId,handle() 中 Order::findOrFail 重新获取并做幂等判断,failed() 中标记支付失败。
派发方式:
- ChargeOrder::dispatch($order->id);
- ChargeOrder::dispatch($order->id)->onQueue('high');
- ChargeOrder::dispatch($order->id)->delay(now()->addMinutes(5));
- ChargeOrder::dispatchAfterResponse($order->id);
Supervisor 推荐配置含 [program:laravel-worker]、command 使用 queue:work redis --queue=high,default,low --sleep=3 --tries=3 --max-time=3600 --backoff=3、stopwaitsecs=3600 等项。关键点:stopwaitsecs 必须大于最长任务的超时时间,否则部署时 Supervisor 会在任务中途将其杀死。
适用场景与限制
技能明确限定范围:PHP / Laravel 13 + MySQL + Redis(队列),可选 Horizon;版本 1.0.0,含 6 大类 20 条规则,许可证 MIT。参考资料为 Laravel 13 的 Queues、Horizon、Task Scheduling 文档以及 Supervisor 进程控制系统;完整指南见 AGENTS.md。除上述范围外,其他框架版本、其他数据库或云平台的适配情况暂未提供。