关于 laravel-queues
面向 Laravel 13 队列开发与运维的技能,包含 20 条规则,覆盖队列配置、任务设计、重试、扩展和测试。支持针对代码与配置进行清单式审查,并优先识别可能在生产负载下出问题的模式。
主要功能
- 01涵盖 6 类队列规则
- 02审查队列配置和任务类
- 03检查重试与失败处理
- 04指导工作进程扩展和回收
- 05支持批处理、链式任务与测试
适用场景
- 01设计或审查后台任务
- 02排查卡住或反复失败的任务
- 03配置 Redis 队列工作进程
- 04规划队列测试与 Horizon 使用
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ asyrafhussin/ agent-skills --skill laravel-queues安装后在 Claude Code 中输入/laravel-queues确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
AGENTS.mdmetadata.jsonREADME.mdrules/_sections.md_template.mdbus-batch-failure-handling.mdbus-batch-vs-chain.mdbus-chunking-large-sets.mdconfig-after-commit.mdconfig-driver-choice.mdconfig-failed-storage.mddesign-constructor-vs-handle.mddesign-idempotency.mddesign-pass-ids-not-models.mddesign-shouldqueue.mdops-horizon-when.mdops-queue-fake.mdops-schedule-queued-jobs.mdretry-fail-on-timeout.mdretry-failed-method.mdretry-transient-vs-permanent.mdretry-tries-and-backoff.mdscaling-multi-queue-priority.mdscaling-supervisor-config.mdscaling-worker-recycling.md详细介绍
Laravel 队列与任务
适用于 Laravel 13(MySQL + Redis)的生产级队列模式。包含 6 个类别中的 20 条规则,涵盖驱动选择、任务设计、重试与失败处理、工作进程扩缩容、批处理与链式调度以及测试。重点关注那些通过代码审查、却会在负载下出问题的故障模式——重试时悄无声息地重新调度、序列化后模型过时、支付任务缺少幂等性、工作进程内存泄漏,以及“我们忘了实现 ShouldQueue,导致请求在生产环境中耗时 12 秒”。
元数据
- 版本: 1.0.0
- 范围: PHP / Laravel 13 + MySQL + Redis(队列),可选 Horizon
- 规则数量: 6 个类别中的 20 条规则
- 许可证: MIT
使用方法
当用户询问“设计这个后台任务”“审查我们的队列配置”“为什么这个任务没有运行”或其他与队列相关的问题时,请将此技能的规则作为检查清单,对照相关文件逐项检查(任务类、config/queue.php、config/horizon.php、Supervisor 配置以及调度调用位置)。
在审查模式下,按规则输出结论:
- PASS — 已正确应用此模式
- FAIL — 存在反模式(注明文件路径和行号,并给出修复建议)
- N/A — 不适用于此代码库
最后列出优先级最高的修复项(支付任务的幂等性、缺少 ShouldQueue、Supervisor 的 stopwaitsecs 设置过低——这些是生产环境中最常见的问题)。
适用场景
在以下情况下参考此技能:
- 编写新的后台任务(
php artisan make:job) - 审查新增或修改任务类的 PR
- 在新服务器上设置队列工作进程(Forge / Vapor / 裸机服务器)
- 配置
config/queue.php或config/horizon.php - 调试卡住、循环运行或反复失败的任务
- 在
dispatch()、dispatchSync()、dispatchAfterResponse()、Bus::batch()、Bus::chain()之间做出选择 - 添加队列测试(
Queue::fake()、Bus::fake()) - 决定是否采用 Horizon
第 1 步:检测队列配置
检查:
| 文件 | 需要了解的内容 |
|---|---|
config/queue.php | 默认连接(QUEUE_CONNECTION 环境变量)、失败任务存储、after_commit 设置 |
config/horizon.php(如果存在) | Horizon 环境、均衡策略、工作进程数量、超时设置 |
app/Jobs/*.php | 任务类、ShouldQueue 用法、tries / backoff、failed() 方法 |
app/Console/Kernel.php 或 routes/console.php | 计划任务(Schedule::job(...)、withoutOverlapping) |
database/migrations/*_create_failed_jobs_table.php | 失败任务存储迁移;或配置中的 DynamoDB 驱动 |
supervisor*.conf / /etc/supervisor/conf.d/ | 工作进程管理、numprocs、--max-time、stopwaitsecs |
典型配置:
| 技术栈 | 队列驱动 | 失败任务驱动 | 工作进程管理器 |
|---|---|---|---|
| 小型 Laravel + MySQL | database | database | Supervisor(或 systemd) |
| 生产环境 Laravel + Redis | redis | database(无服务器环境下也可使用 dynamodb) | Supervisor + Horizon |
| Laravel Vapor | sqs | dynamodb | Vapor 管理 |
按优先级排列的规则类别
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
| 1 | 驱动与配置 | 严重 | config- |
| 2 | 任务设计 | 严重 | design- |
| 3 | 重试与失败处理 | 高 | retry- |
| 4 | 扩缩容与工作进程 | 高 | scaling- |
| 5 | 批处理与链式调度 | 高 | bus- |
| 6 | 测试与运维 | 中 | ops- |
快速参考
1. 驱动与配置(严重)
config-driver-choice— 小型应用使用database;生产规模使用redis;Laravel Vapor 使用sqsconfig-after-commit— 设置after_commit: true,以避免调度引用未提交数据库记录的任务config-failed-storage— 必须配置failed_jobs表(Vapor 上使用 DynamoDB);设置保留期限和清理机制
2. 作业设计(关键)
design-shouldqueue— 每个异步作业都必须实现ShouldQueue(最常见的生产环境 Bug:忘记实现会导致作业同步运行)design-pass-ids-not-models— 在构造函数中传递 ID,在handle()中重新获取模型,避免模型过时以及序列化后的负载过大design-idempotency— 支付、外部 API 和“创建资源”作业必须能够安全地重复运行两次(ShouldBeUnique、幂等键、唯一数据库约束)design-constructor-vs-handle— 构造函数在分发时运行(同步);handle()在工作进程中运行。不要在构造函数中写入数据库或调用 HTTP。
3. 重试与失败(高)
retry-tries-and-backoff— 两者都要设置:使用#[Backoff([1, 5, 30])]设置指数退避延迟;默认重试 3 次通常不足以应对瞬时故障retry-failed-method— 实现failed(Throwable $e)来处理永久性故障(发送警报、退款、标记为失败)retry-transient-vs-permanent— 瞬时错误(限流、网络故障)使用release($delay);永久性错误则抛出异常retry-fail-on-timeout— 使用#[FailOnTimeout],避免超时的作业耗尽所有尝试次数
4. 扩展与工作进程(高)
scaling-supervisor-config— 使用 Supervisor(或 systemd)管理工作进程;stopwaitsecs > timeout;通过--max-time=3600循环回收工作进程scaling-multi-queue-priority— 对 SLA 关键作业使用 high/default/low 队列;--queue=high,default,lowscaling-worker-recycling— 使用--max-jobs和--max-time,应对长期运行的工作进程中的内存泄漏
5. 批处理与链式调度(高)
bus-batch-vs-chain— 使用Bus::batch实现并行处理和进度跟踪;使用Bus::chain实现严格的顺序处理bus-batch-failure-handling— 对容错批处理使用allowFailures();使用then/catch/finally回调bus-chunking-large-sets— 对于 1000 个以上的项目,使用Bus::batch(...)分块处理,而不是每个项目创建一个作业
6. 测试与运维(中)
ops-queue-fake— 在测试中使用Queue::fake()/Bus::fake();使用assertDispatched、assertPushed、assertChained、assertBatchedops-schedule-queued-jobs—Schedule::job(new X)->everyMinute()会将作业加入队列;配合withoutOverlapping()使用以确保安全ops-horizon-when— 使用 Redis 且有多个 Supervisor 时采用 Horizon;不适用于database队列或单工作进程配置
核心模式
最简可用作业类(Laravel 13)
<?php
namespace App\Jobs;
use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\Attributes\Backoff;
use Illuminate\Queue\Attributes\FailOnTimeout;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Throwable;
#[Backoff([1, 5, 30])]
#[FailOnTimeout]
class ChargeOrder implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 5;
public int $timeout = 30;
public function __construct(public readonly int $orderId) {}
public function handle(StripeGateway $stripe): void
{
$order = Order::findOrFail($this->orderId); // refetch — don't trust serialised state
if ($order->status === 'paid') return; // idempotency guard
$charge = $stripe->charge($order);
$order->markPaid($charge->id);
}
public function failed(Throwable $e): void
{
Order::find($this->orderId)?->markPaymentFailed($e->getMessage());
}
}
分发
ChargeOrder::dispatch($order->id); // default queue
ChargeOrder::dispatch($order->id)->onQueue('high'); // priority lane
ChargeOrder::dispatch($order->id)->delay(now()->addMinutes(5));
ChargeOrder::dispatchAfterResponse($order->id); // run after HTTP response sent
Supervisor 配置(推荐)
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/app/artisan queue:work redis --queue=high,default,low --sleep=3 --tries=3 --max-time=3600 --backoff=3
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=forge
numprocs=8
redirect_stderr=true
stdout_logfile=/var/www/app/storage/logs/worker.log
stopwaitsecs=3600
重要: stopwaitsecs 必须大于最长作业的超时时间,否则 Supervisor 会在部署期间终止正在运行的作业。
参考资料
完整文档
查看包含所有展开规则的完整指南:AGENTS.md
评论
支持 Markdown