assetplan/dispatcher

从其他应用程序安全地调度任务

v0.3.3 2023-05-29 20:33 UTC

This package is auto-updated.

Last update: 2024-08-29 23:33:32 UTC


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)。请参阅许可证文件以获取更多信息。