romanzipp/laravel-queue-monitor

Laravel 数据库作业队列的队列监控

5.3.4 2024-09-09 12:20 UTC

README

Latest Stable Version Total Downloads License GitHub Build Status

本包提供类似 Laravel Horizon 的数据库队列监控功能。

功能

  • 监控任何队列的作业,如 Laravel Horizon
  • 处理失败的作业,存储异常
  • 监控作业进度
  • 获取作业剩余时间的估算值
  • 为作业监控存储附加数据
  • 通过界面重试作业

安装

composer require romanzipp/laravel-queue-monitor

有一个额外的包 romanzipp/Laravel-Queue-Monitor-Nova 用于 Laravel Nova 资源和指标。

升级

✨ 如果你正在更新到 5.0,请参阅 升级指南

配置

将配置和迁移文件复制到你的项目中

php artisan vendor:publish --provider="romanzipp\QueueMonitor\Providers\QueueMonitorProvider" --tag=config --tag=migrations

迁移队列监控表。表名可以在配置文件或发布的迁移中进行配置。

php artisan migrate

使用

要监控作业,只需添加 romanzipp\QueueMonitor\Traits\IsMonitored 特性。

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use romanzipp\QueueMonitor\Traits\IsMonitored; // <---

class ExampleJob implements ShouldQueue
{
    use Dispatchable;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;
    use IsMonitored; // <---
}

重要! 您需要将 Illuminate\Contracts\Queue\ShouldQueue 接口实现到您的作业类中。否则,Laravel 不会派发任何包含状态信息的作业事件以进行监控。

网络界面

您可以通过将 ui.enabled 设置为 true 配置值来启用网络界面。

发布前端资源

php artisan vendor:publish --provider="romanzipp\QueueMonitor\Providers\QueueMonitorProvider" --tag=assets

有关更多信息,请参阅 完整的配置文件

Preview Preview

命令

artisan queue-monitor:stale

此命令将旧的监控条目标记为 过时。您应该在控制台内核中定期运行此命令。

参数和选项

  • --before={date} 在此日期之前的所有条目都将被标记为过时
  • --beforeDays={days} 相对于过时条目的天数
  • --beforeInterval={interval} 在此之前条目将被标记为过时的间隔日期字符串
  • --dry 仅进行 dry 运行

artisan queue-monitor:purge

此命令删除旧的监控模型。

参数和选项

  • --before={date} 在此日期之前的所有条目将被删除
  • --beforeDays={days} 相对于要删除条目的天数
  • --beforeInterval={interval} 在此之前条目将被删除的间隔日期字符串
  • --queue={queue} 仅清除特定的队列(以逗号分隔的值)
  • --only-succeeded 仅清除成功条目
  • --dry 仅进行 dry 运行

需要提供 beforebeforeDate 参数之一。

高级使用

进度

您可以为 进度值(0-100)设置以获取作业进度的估算值。

use Illuminate\Contracts\Queue\ShouldQueue;
use romanzipp\QueueMonitor\Traits\IsMonitored;

class ExampleJob implements ShouldQueue
{
    use IsMonitored;

    public function handle()
    {
        $this->queueProgress(0);

        // Do something...

        $this->queueProgress(50);

        // Do something...

        $this->queueProgress(100);
    }
}

块进度

一个常见的任务场景是迭代处理大量集合。

这个示例任务会循环处理大量用户,并在每次数据块迭代时更新其进度值。

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\Eloquent\Collection;
use romanzipp\QueueMonitor\Traits\IsMonitored;

class ChunkJob implements ShouldQueue
{
    use IsMonitored;

    public function handle()
    {
        $usersCount = User::count();

        $perChunk = 50;

        User::query()
            ->chunk($perChunk, function (Collection $users) use ($perChunk, $usersCount) {

                $this->queueProgressChunk($usersCount‚ $perChunk);

                foreach ($users as $user) {
                    // ...
                }
            });
    }
}

进度冷却

为了避免快速重复的更新查询导致数据库过载,您可以重写 progressCooldown 方法并指定每次进度更新写入数据库前等待的秒数。请注意,对于值 0、25、50、75 和 100,冷却时间将被忽略。

use Illuminate\Contracts\Queue\ShouldQueue;
use romanzipp\QueueMonitor\Traits\IsMonitored;

class LazyJob implements ShouldQueue
{
    use IsMonitored;

    public function progressCooldown(): int
    {
        return 10; // Wait 10 seconds between each progress update
    }
}

自定义数据

此包还允许在监控模型上使用数组语法设置自定义数据。

use Illuminate\Contracts\Queue\ShouldQueue;
use romanzipp\QueueMonitor\Traits\IsMonitored;

class CustomDataJob implements ShouldQueue
{
    use IsMonitored;

    public function handle()
    {
        $this->queueData(['foo' => 'Bar']);
        
        // WARNING! This is overriding the monitoring data
        $this->queueData(['bar' => 'Foo']);

        // To preserve previous data and merge the given payload, set the $merge parameter true
        $this->queueData(['bar' => 'Foo'], true);
    }
}

为了在 UI 上显示自定义数据,您需要在 config/queue-monitor.php 文件下添加此行。

'ui' => [
    ...

    'show_custom_data' => true,

    ...
]

初始数据

此包还允许设置在任务排队时设置的初始数据。

use Illuminate\Contracts\Queue\ShouldQueue;
use romanzipp\QueueMonitor\Traits\IsMonitored;

class InitialDataJob implements ShouldQueue
{
    use IsMonitored;
    
    public function __construct(private $channel)
    {
    }

    public function initialMonitorData()
    {
        return ['channel_id' => $this->channel];
    }
}

仅保留失败的任务

您可以通过重写 keepMonitorOnSuccess() 方法来仅存储已执行任务的失败监控条目。如果您只想保留频繁执行但值得监控的失败的监控,可以使用此功能。或者,您还可以使用 Laravel 内置的 failed_jobs 表。

use Illuminate\Contracts\Queue\ShouldQueue;
use romanzipp\QueueMonitor\Traits\IsMonitored;

class FrequentSucceedingJob implements ShouldQueue
{
    use IsMonitored;

    public static function keepMonitorOnSuccess(): bool
    {
        return false;
    }
}

检索已处理的任务

use romanzipp\QueueMonitor\Models\Monitor;

$job = Monitor::query()->first();

// Check the current state of a job
$job->isFinished();
$job->hasFailed();
$job->hasSucceeded();

// Exact start & finish dates with milliseconds
$job->getStartedAtExact();
$job->getFinishedAtExact();

// If the job is still running, get the estimated seconds remaining
// Notice: This requires a progress to be set
$job->getRemainingSeconds();
$job->getRemainingInterval(); // Carbon\CarbonInterval

// Retrieve any data that has been set while execution
$job->getData();

// Get the base name of the executed job
$job->getBasename();

模型作用域

use romanzipp\QueueMonitor\Models\Monitor;

// Filter by Status
Monitor::failed();
Monitor::succeeded();

// Filter by Date
Monitor::lastHour();
Monitor::today();

// Chain Scopes
Monitor::today()->failed();

测试

在本地执行测试的最简单方法是使用 Lando。自动启动应用和数据库容器的Lando 配置文件

lando start

lando phpunit-sqlite
lando phpunit-mysql
lando phpunit-postgres

升级

许可证

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

此包受到了 gilbitron 的 laravel-queue-monitor 的启发,该包已不再维护。

Star History Chart