smskin/laravel-dynamic-horizon

为 Laravel Horizon 提供动态管理者和队列

1.0.0 2024-09-20 08:01 UTC

This package is auto-updated.

Last update: 2024-09-20 08:02:51 UTC


README

我遇到了需要在 Horizon 中程序化管理进程和队列的需求,以解决以下情况

我的用户在队列中生成任务。如果一个用户生成 100 万个任务,则第二个用户必须等待队列清除。标准的 Horizon 解决方案将不起作用,因为消费者和队列在配置文件中是静态配置的。由于有大量用户,为每个用户创建 X 个队列将是一个非常耗资源的解决方案,因为队列大部分时间都将处于空闲状态(每个 Horizon 消费者都是一个单独的进程,消耗操作系统资源)。

解决方案:按需创建消费者并在不使用时停止它们。

操作原理

该库基于监听标准的 Horizon MasterSupervisorLooped 事件(Horizon 主进程周期的完成)。

在每个周期的每个 tick,都会轮询当前动态管理者的配置(存储在 Redis 中),并按需启动/停止管理者。

库功能

此库不会以任何方式修改 Horizon。它旨在“并存”并互不干扰。当配置更改时,需要一些时间(Horizon 进程的 tick)才能启动新的管理者。

用法

  1. 获取动态管理者的列表
use SMSkin\LaravelDynamicHorizon\DynamicHorizon;

$supervisors = (new DynamicHorizon())->getSupervisors();
  1. 设置管理者的配置
use SMSkin\LaravelDynamicHorizon\DynamicHorizon;  
use SMSkin\LaravelDynamicHorizon\Models\Supervisor;

(new DynamicHorizon())->setSupervisors(collect([
    new Supervisor(
        'user1-supervisor',
        [
            'user1-queue',
        ]
    ),
    new Supervisor(
        'user2-supervisor',
        [
            'user2-queue-1',
            'user2-queue-2',
        ]
    )
]))

set configuration screenshot

  1. 将管理者添加到配置中
use SMSkin\LaravelDynamicHorizon\DynamicHorizon;  
use SMSkin\LaravelDynamicHorizon\Models\Supervisor;

(new DynamicHorizon())->addSupervisor(
    new Supervisor(
        'user3-supervisor',
        [
            'user3-queue',
        ]
    )
);

add supervisor screenshot

  1. 更新其中一个管理者的配置
use SMSkin\LaravelDynamicHorizon\DynamicHorizon;  
use SMSkin\LaravelDynamicHorizon\Models\Supervisor;

(new DynamicHorizon())->updateSupervisor(
    new Supervisor(
        'user3-supervisor',
        [
            'user3-queue-1',
            'user3-queue-2',
        ]
    )
);

update supervisor screenshot

  1. 停止其中一个管理者
use SMSkin\LaravelDynamicHorizon\DynamicHorizon;  
use SMSkin\LaravelDynamicHorizon\Models\Supervisor;

(new DynamicHorizon())->stopSupervisor(
    new Supervisor(
        'user1-supervisor',
        [
            'user1-queue',
        ]
    )
);

stop supervisor screenshot

  1. 停止所有动态管理者
use SMSkin\LaravelDynamicHorizon\DynamicHorizon;  

(new DynamicHorizon())->stopAllSupervisors();

stop all supervisors screenshot