timmylindh/laravel-beanstalk-worker

提供在AWS Elastic Beanstalk工作环境中利用Laravel SQS队列和cron作业的功能

v1.1.0 2024-05-02 23:33 UTC

This package is auto-updated.

Last update: 2024-09-23 13:34:26 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

提供在AWS Elastic Beanstalk工作环境中利用Laravel SQS队列和cron作业的功能。

该包支持所有Laravel队列和cron功能,如重试、回退、延迟、释放、最大尝试次数、超时等。

安装

要求

  • Laravel >= 10
  • PHP >= 8.1

您可以通过composer安装此包

composer require timmylindh/laravel-beanstalk-worker

您可以使用以下命令发布配置文件:

php artisan vendor:publish --tag="laravel-beanstalk-worker-config"

用法

启用工作进程

将环境变量IS_WORKER设置为启用工作进程路由。

IS_WORKER=true

然后在AWS Elastic Beanstalk工作环境中将HTTP路径指向/worker/queue。这将自动将所有SQS消息发送到工作进程。

启用cron

在您的Laravel根项目文件夹中添加文件cron.yaml,内容如下。这将告诉AWS守护进程每分钟发布一个SQS cron任务消息,该消息将发送到我们的工作进程,以运行计划中的cron作业。

version: 1
cron:
    - name: "cron"
      url: "/worker/cron"
      schedule: "* * * * *"

配置

您可以使用以下命令发布配置文件:

php artisan vendor:publish --tag="laravel-beanstalk-worker-config"

配置包含各种属性,用于控制运行您的排队作业的工作进程。这些与您使用php artisan queue:work在本地运行工作进程时提供的相同。

return [
    /*
     * Whether the application is a worker or not.
     * This will determine whether to register the worker routes or not.
     */
    "is_worker" => env("IS_WORKER", false),

    // The number of seconds to wait before retrying a job that encountered an uncaught exception.
    "backoff" => env("WORKER_BACKOFF", 0),

    // The number of seconds a job may run before timing out.
    'timeout' => env('WORKER_TIMEOUT', 60),

    // The maximum number of times a job may be attempted.
    "max_tries" => env("WORKER_MAX_TRIES", 1),
];

AWS Elastic Beanstalk

在AWS Elastic Beanstalk工作进程中,您还可以设置其他选项。

  • 最大重试次数:这将被忽略并由包的max_tries属性覆盖。应设置为一个大于任何作业期望的最大max_tries的值。
  • 可见性超时:在将作业释放回队列之前等待作业完成的秒数。应大于任何作业期望的最大timeout
  • 非活动超时:应与可见性超时相同。
  • 最大执行时间:应与可见性超时相同。
  • 错误可见性超时:这将被忽略并由包的backoff属性覆盖。当发生超时时,这将(而不是超时)控制在重试作业之前等待的秒数。

处理超时

要正确处理超时,您应确保将Elastic Beanstalk属性设置为如下:

最大重试次数 > max(max_retries|$tries, for any job)

可见性超时 > max(timeout|$timeout, for any job)

错误可见性超时 >= 0:这将控制在重试超时作业之前等待的秒数。

示例:如果预计所有作业最多重试4次,最大超时时间为250秒,则将最大重试次数 = 5可见性超时 = 252

有关更多详细信息,请参阅上面的配置部分。

工作原理

通常,在标准服务器环境中,Laravel队列工作进程是通过执行命令php artisan queue:work设置的。然而,由于平台架构,在AWS Elastic Beanstalk中设置它可能具有挑战性。

Elastic Beanstalk中的工作环境

弹性Beanstalk支持与Amazon SQS无缝集成的worker环境。这些环境包含一个SQS守护进程,该守护进程会持续轮询队列,通过将任务转发到您的应用程序指定的URL端点来获取和执行任务。

自动消息处理

  • 成功处理:如果应用程序的端点返回HTTP 2xx状态码,守护进程将其解释为任务成功完成,并自动从队列中删除消息。
  • 失败处理:如果端点返回非2xx状态码,守护进程将重新入队消息。任务将在错误可见性超时期间后重试,并持续进行,直到达到最大重试次数限制。

挑战

在此设置中,一个重大挑战是失去了对每个任务最大尝试次数的控制以及任务重试前的延迟(回退策略)。

解决方案

为了解决这些问题,我们使用了一个专门的路线/worker/queue,该路线设计为无论任务的实际结果如何,总是返回HTTP 2xx状态码。这确保了SQS守护进程在第一次出队后删除任务。

  • 错误处理:如果任务失败,我们调用report()来记录异常,确保故障的可见性和可追溯性。
  • 任务重试:我们覆盖了Laravel的默认release()方法。这允许我们手动使用增加的attempts计数和自定义的delay重新入队失败的任务,从而更精确地管理重试机制。

这种方法紧密模拟了在Elastic Beanstalk环境中运行标准Laravel worker使用Artisan的行为。

测试

composer test

致谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件