assetplan / dispatcher
从其他应用程序安全地调度任务
Requires
- php: ^8.1
- illuminate/support: ^10.0
Requires (Dev)
- laravel/pint: ^1.10
- orchestra/testbench: ^8.0
- phpunit/phpunit: ^10.0
README
Assetplan Dispatcher 是一个轻量级的 PHP 包,允许您使用 HTTP 请求在多个应用程序之间调度任务。这在需要在不同机器上执行任务的分布式系统中非常有用。
安装
您可以通过 composer 安装此包
composer require assetplan/dispatcher
用法
设置后端
在您开始调度任务之前,您需要设置一个后端应用程序来接收调度的任务。这可以是任何可以处理 HTTP 请求的 PHP 应用程序。您需要设置以下环境变量来配置后端
# in the backend
DISPATCHER_BACKEND_SECRET=your-secret
DISPATCHER_IS_BACKEND=true
# in the machine that will dispatch the jobs
DISPATCHER_BACKEND_URL=https://:8000
DISPATCHER_BACKEND_SECRET=your-secret
DISPATCHER_BACKEND_URL
变量应指向后端应用程序的 URL。DISPATCHER_BACKEND_SECRET
变量是一个共享密钥,用于对调度的任务进行签名。请确保保持此密钥的安全。
生成密钥
dispatcher:generate-secret
命令允许您生成用于对调度的任务进行签名的密钥。您可以使用此命令生成新的密钥或替换现有的密钥。
要生成新的密钥,请运行以下命令
php artisan dispatcher:generate-secret
默认情况下,该命令生成一个 64 字符的密钥并将其保存到应用程序的 .env 文件中。如果 .env 文件不存在,该命令将显示错误信息。
您可以使用 --length
选项指定密钥的长度。例如,要生成一个 128 字符的密钥,请运行以下命令
php artisan dispatcher:generate-secret --length=128
您可以使用 --show 选项在控制台显示生成的密钥。例如,要生成新的密钥并在控制台显示它,请运行以下命令
php artisan dispatcher:generate-secret --show
您可以使用 --no-replace 选项在不替换现有密钥的情况下生成新的密钥。例如,要生成新的密钥而不替换现有的密钥,请运行以下命令
php artisan dispatcher:generate-secret --no-replace
如果 .env
文件已经包含 DISPATCHER_BACKEND_SECRET
变量,该命令将用新生成的密钥替换其值。如果 .env
文件不包含 DISPATCHER_BACKEND_SECRET
变量,则该命令将添加变量及其值到文件中。
注意: 如果您在生产环境中运行该命令,则该命令将显示警告消息并退出而不生成新的密钥。这是为了防止意外更改生产设置。
配置
该包附带一个配置文件,允许您自定义其行为。您可以通过运行以下命令发布配置文件
php artisan vendor:publish --provider="Assetplan\Dispatcher\DispatcherServiceProvider" --tag="config"
发布配置文件后,您可以自定义以下选项
url
:将任务调度到后端服务器的 URL。secret
:在调度任务之前用于签名的密钥。is_backend
:当前服务器是否为后端服务器。aliases
:您可以注册别名,以便更容易地调度任务。这些别名只需要在后台服务器上注册,是可选的。
别名
《aliases》配置选项允许您为作业类注册自定义别名。这可以在每次调度作业时避免输入完整的类名。
以下是在dispatcher.php配置文件中注册别名的示例
<?php 'aliases' => [ 'send-welcome-email' => 'App\Jobs\SendWelcomeEmail', ],
然后您可以在调度作业时使用该别名
<?php $dispatcher->dispatch('send-welcome-email', ['user' => $user]);
注意:注册别名是可选的,并且只需在后端服务器中执行。
调度作业
要从您的应用程序中调度作业,请使用Dispatcher类的dispatch方法。此方法需要两个参数
$job
:要调度的作业类的完整限定名称。$payload
:要传递给作业的数据数组。
以下是一个示例
<?php use Assetplan\Dispatcher\Dispatcher; use Illuminate\Http\Request; class ExampleController { public function store(Request $request, Dispatcher $dispatcher) { $result = $dispatcher->dispatch(MyJob::class, ['foo' => 'bar']); if ($result->failed()) { // do something if failed dispatch } return $result->getId(); // the result object allows access to the dispatched job id } }
dispatch方法将返回已调度作业的结果。您可以使用此结果跟踪作业的状态或执行进一步处理。
调度一组作业
要调度一组作业,请使用Dispatcher
类的batch
方法。此方法需要三个参数
$jobs
:一个包含Assetplan\Dispatcher\Queue\Job
对象的数组:每个对象包含目标作业的名称及其有效负载$queue
:作业应被调度到的队列$shouldBatch
:是否将批次作为Laravel队列批次调度或单独调度所有作业
以下是一个示例
<?php use Assetplan\Dispatcher\Dispatcher; use App\Jobs\SendWelcomeEmail; use Illuminate\Http\Request; class ExampleController { public function store(Request $request, Dispatcher $dispatcher) { $jobs = [ new Job( SendWelcomeEmail::class, ['email'=>'user@example.com'] ), new Job( 'App\Jobs\InviteToUserGroup', ['email'=>'user@example.com'] ), ]; $result = $dispatcher->batch($jobs, 'emails', shouldBatch: true); if ($result->failed()) { // do something if failed dispatch } return $result->getId(); // the result object allows access to the dispatched batch id } }
注意:在shouldBatch=false
的情况下调度时,批次ID将生成为本地的批次UUID。
一些最终考虑
- 此包是针对特定问题的轻量级解决方案。
- 当创建可以从其他应用程序使用
dispatcher
调度的Jobs
时,请考虑使用模型ID或array
参数以保持HTTP有效负载的大小可控。 - 如果您需要调度大量作业,请考虑分块处理它们或调度一个单独的作业以调度批次。
致谢
许可证
MIT许可证(MIT)。请参阅许可证文件以获取更多信息。