mcpField
L
laravel-queues

laravel-queues

github.com/asyrafhussin开发95712 次安装9 周前更新
代码仓库

关于 laravel-queues

面向 Laravel 13 队列开发与运维的技能,包含 20 条规则,覆盖队列配置、任务设计、重试、扩展和测试。支持针对代码与配置进行清单式审查,并优先识别可能在生产负载下出问题的模式。

主要功能

  1. 01涵盖 6 类队列规则
  2. 02审查队列配置和任务类
  3. 03检查重试与失败处理
  4. 04指导工作进程扩展和回收
  5. 05支持批处理、链式任务与测试

适用场景

  1. 01设计或审查后台任务
  2. 02排查卡住或反复失败的任务
  3. 03配置 Redis 队列工作进程
  4. 04规划队列测试与 Horizon 使用

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/asyrafhussin/agent-skills --skill laravel-queues

安装后在 Claude Code 中输入/laravel-queues确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

AGENTS.md
metadata.json
README.md
rules/
_sections.md
_template.md
bus-batch-failure-handling.md
bus-batch-vs-chain.md
bus-chunking-large-sets.md
config-after-commit.md
config-driver-choice.md
config-failed-storage.md
design-constructor-vs-handle.md
design-idempotency.md
design-pass-ids-not-models.md
design-shouldqueue.md
ops-horizon-when.md
ops-queue-fake.md
ops-schedule-queued-jobs.md
retry-fail-on-timeout.md
retry-failed-method.md
retry-transient-vs-permanent.md
retry-tries-and-backoff.md
scaling-multi-queue-priority.md
scaling-supervisor-config.md
scaling-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 + MySQLdatabasedatabaseSupervisor(或 systemd)
生产环境 Laravel + Redisredisdatabase(无服务器环境下也可使用 dynamodb)Supervisor + Horizon
Laravel VaporsqsdynamodbVapor 管理

按优先级排列的规则类别

优先级类别影响前缀
1驱动与配置严重config-
2任务设计严重design-
3重试与失败处理高retry-
4扩缩容与工作进程高scaling-
5批处理与链式调度高bus-
6测试与运维中ops-

快速参考

1. 驱动与配置(严重)
  • config-driver-choice — 小型应用使用 database;生产规模使用 redis;Laravel Vapor 使用 sqs
  • config-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,low
  • scaling-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、assertBatched
  • ops-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