dusterio / laravel-aws-worker
在 AWS Elastic Beanstalk 工作器中运行 Laravel(或 Lumen)任务和队列监听器
Requires
- php: >=5.5.0
- aws/aws-sdk-php: ~3.0
- illuminate/bus: 5.*|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0
- illuminate/http: 5.*|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0
- illuminate/queue: 5.*|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0
- illuminate/support: 5.*|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0
Requires (Dev)
- codeclimate/php-test-reporter: dev-master
- phpunit/phpunit: 3.7.*|^9.5.10|^10.5
- dev-master
- v1.0.02
- v1.0.01
- v1.0.00
- v0.1.40
- v0.1.39
- v0.1.38
- v0.1.37
- v0.1.36
- v0.1.35
- v0.1.34
- v0.1.33
- v0.1.32
- v0.1.31
- v0.1.30
- v0.1.29
- v0.1.28
- v0.1.27
- v0.1.26
- v0.1.25
- v0.1.24
- v0.1.23
- v0.1.22
- v0.1.21
- v0.1.20
- v0.1.19
- v0.1.18
- v0.1.17
- v0.1.16
- v0.1.15
- v0.1.14
- v0.1.13
- v0.1.12
- v0.1.11
- v0.1.10
- v0.1.9
- v0.1.8
- v0.1.7
- v0.1.6
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
This package is auto-updated.
Last update: 2024-08-29 06:52:57 UTC
README
在 AWS Elastic Beanstalk 工作器中运行 Laravel 任务和队列监听器
我们已停止对 Lumen 的未来支持,但您仍然可以使用 v0.1.40 版本用于 Lumen。
概述
Laravel 文档建议使用 supervisor 作为队列工作进程和 *IX cron 作为计划任务。然而,当将您的应用程序部署到 AWS Elastic Beanstalk 时,这两个选项都不可用。
此软件包帮助您在 AWS 工作环境上运行 Laravel 作业。
依赖
- PHP >= 5.5
- Laravel >= 5.1
计划任务 - 选项 1
第一个选项是使用 Kernel.php 作为计划,并每分钟运行 Laravel 计划运行器。你还记得 Laravel 文档建议如何调用任务调度器吗?没错,通过定期运行 php artisan schedule:run
,为了做到这一点,我们不得不将条目添加到我们的 crontab 文件中
* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1
AWS 允许您运行 *IX 命令或直接添加 crontab 任务。相反,您必须定期向您的工人端点发出 HTTP(POST,更准确地说)请求。
将 cron.yaml 添加到您的应用程序根目录中(这可以是您仓库的一部分,或者您可以在部署到 EB 之前添加此文件 - 重要的是确保在部署时此文件存在)
version: 1 cron: - name: "schedule" url: "/worker/schedule" schedule: "* * * * *"
从现在开始,AWS 将每分钟向您的端点发出 POST /worker/schedule 请求 - 类似于我们在编辑 UNIX crontab 文件时所达到的效果。这里的重要区别在于,工作环境仍然需要运行一个网络进程来执行计划任务。在幕后,它将执行类似于内置的 schedule:run
命令的操作。
您的计划任务应在 App\Console\Kernel::class
中定义 - 就像在 Laravel 中一样正常,例如。
protected function schedule(Schedule $schedule) { $schedule->command('inspire') ->everyMinute(); }
计划任务 - 选项 2
第二个选项是使用 cron.yml 中定义的 AWS 计划
version: 1 cron: - name: "run:command" url: "/worker/schedule" schedule: "0 * * * *" - name: "do:something --param=1 -v" url: "/worker/schedule" schedule: "*/5 * * * *"
注意,AWS 将使用 UTC 时区为 cron 表达式。在上面的示例中,AWS 将每小时调用 /worker/schedule 端点一次,使用 run:command
artisan 命令,每 5 分钟调用一次 do:something
命令。目前不支持命令参数。
选择最适合您的选项!
队列作业:SQS
通常 Laravel 需要轮询 SQS 以获取新消息,但在 AWS Elastic Beanstalk 的情况下,消息将来自 AWS 守护进程的 POST 请求。
因此,我们将根据到达的 SQS 有效负载手动创建作业,并将该作业传递给框架的默认工作进程。从这一点开始,作业将以 Laravel 中通常处理的方式进行处理。如果处理成功,我们的控制器将返回 200 HTTP 状态,AWS 守护进程将删除队列中的作业。再次强调,我们不需要轮询作业,我们也不需要删除作业 - 在此情况下,这是 AWS 完成的。
如果您从 Laravel 的另一个实例分发作业,或者如果您遵循 Laravel 的有效负载格式 {"job":"","data":""}
,那么您应该没问题。如果您想接收自定义格式的 JSON 消息,您可能还需要安装 Laravel plain SQS 软件包。
配置队列
每次在AWS中创建工作环境时,都必须选择两个SQS队列——要么是自动生成的,要么是您现有的某些队列。其中一个队列用于工作本身,另一个队列用于失败的工作——AWS将此队列称为死信队列。
您可以在环境启动时或在之后的任何时候设置工作队列。
别忘了将HTTP路径设置为/worker/queue
——AWS将在这里调用我们的应用程序。如果您选择自动生成队列,您可以在AWS控制台的SQS部分稍后查看它们的详细信息。
您必须告诉Laravel关于这个队列。首先,在.env
文件中将队列驱动程序设置为SQS。
QUEUE_DRIVER=sqs
然后转到config/queue.php
并从AWS控制台复制粘贴详细信息。
... 'sqs' => [ 'driver' => 'sqs', 'key' => 'your-public-key', 'secret' => 'your-secret-key', 'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id', 'queue' => 'your-queue-name', 'region' => 'us-east-1', ], ...
要生成密钥和密钥,请转到AWS控制台的“身份与访问管理”。最好创建一个仅具有SQS访问权限的单独用户。
通过Composer安装
要安装,只需运行
composer require dusterio/laravel-aws-worker
或者手动将其添加到composer.json
。
{ "require": { "dusterio/laravel-aws-worker": "~0.1" } }
Laravel 5中的使用
// Add in your config/app.php 'providers' => [ '...', 'Dusterio\AwsWorker\Integrations\LaravelServiceProvider', ];
添加服务提供者后,您应该能够看到我们添加的两个特殊路由。
$ php artisan route:list +--------+----------+-----------------+------+----------------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+-----------------+------+----------------------------------------------------------+------------+ | | POST | worker/queue | | Dusterio\AwsWorker\Controllers\WorkerController@queue | | | | POST | worker/schedule | | Dusterio\AwsWorker\Controllers\WorkerController@schedule | | +--------+----------+-----------------+------+----------------------------------------------------------+------------+
环境变量REGISTER_WORKER_ROUTES
用于触发上述两个路由的绑定。如果您同时在Web和工作环境中运行相同的应用程序,别忘了在您的Web环境中将REGISTER_WORKER_ROUTES
设置为false
。您不希望常规用户能够调用调度器或队列工作。
目前此变量默认设置为true
。
所以就是这样——如果您(或AWS)调用/worker/queue
,Laravel将处理一个队列项(通过POST提供)。如果您调用/worker/schedule
,我们将运行调度器(与在shell中运行php artisan schedule:run
相同)。
Lumen 5中的使用
// Add in your bootstrap/app.php $app->register(Dusterio\AwsWorker\Integrations\LumenServiceProvider::class);
错误和异常
请确保这两个特殊路由没有放在CSRF中间件后面。我们的POST不是真正的Web表单,这里不需要CSRF。如果您有一个全局CSRF中间件,将这些路由添加到异常中,或者将CSRF应用于特定路由或路由组。
如果您的作业失败,我们将抛出FailedJobException
。如果您想自定义错误输出,只需自定义您的异常处理器。请注意,您的HTTP状态代码必须与200不同,以便AWS意识到作业已失败。
作业过期(保留)
一个新特性是能够设置作业过期(在AWS术语中称为保留)以秒为单位,以便在由于负载导致的临时队列延迟的情况下,完全跳过低价值作业。
假设我们有队列作业的激增,现在几分钟过去了,其中一些作业甚至已经没有意义了——我们不希望花费计算资源在以后处理它们。
通过在作业或监听器类上设置特殊属性
class PurgeCache implements ShouldQueue { public static int $retention = 300; // If this job is delayed more than 300 seconds, skip it }
我们可以确保我们不会在队列后300秒后运行此作业。这类似于AWS SQS的“消息保留”设置,只能为整个队列全局设置。
要使用此新功能,您必须使用提供的Jobs\CallQueuedHandler
类,该类扩展了Laravel的默认CallQueuedHandler
。当过期作业到达时,将抛出特殊的ExpiredJobException
异常,然后由您决定如何处理它们。
如果您只是捕获这些异常,因此阻止Laravel向AWS守护进程返回500状态码,则AWS将自动删除作业。
待办事项
- 添加对AWS死信队列的支持(从该队列重试作业?)
视频教程
我刚刚开始了一个教育YouTube频道,该频道将涵盖软件开发和DevOps中的顶级IT趋势:config.sys
此外,我很高兴宣布我的一个新工具——GrammarCI,这是一个针对开发者的自动化错别字/语法检查工具,是CI/CD管道的一部分。
影响
请注意,AWS cron不保证100%的时间准确性。由于cron任务与其他作业共享相同的队列,您的计划任务可能会晚于预期进行处理。
后记
我写了一篇博客文章,解释了这是如何实际工作的。