Laravel Horizon - это простой способ начать работу с очередями Laravel, уменьшив объем конфигурации для создания и управления работниками очереди. Однако понимание того, как создаются рабочие процессы очереди и в каком порядке обрабатываются задания, может быть немного неясным при запуске, особенно если вы вообще не знакомы с очередями.

В этой статье я углублюсь и объясню:

  • Сколько рабочих процессов порождает Laravel Horizon?
  • Если у меня несколько очередей, например очереди high и default
    - сколько рабочих процессов создается Laravel Horizon?
    - в каком порядке выполняются задания?

В Horizon есть опция balance, которая принимает false, simple или auto. balance option напрямую влияет на создание рабочих и выполнение заданий.

Начнем с самого простого варианта balance=false

баланс = ложь

В документации сказано:

Когда для параметра balance установлено значение false, будет использоваться поведение Laravel по умолчанию, которое обрабатывает очереди в том порядке, в котором они перечислены в вашей конфигурации.

В случае balance=false рабочие процессы создаются следующим образом:

  1. Создайте рабочие процессы, равные числу, которое вы установили для processes в config/horizon.php.

Порядок выполнения задания:

  • Рабочие всегда будут обрабатывать задания в том порядке, в котором вы определяете queues в config/horizon.php.

Примеры? Да, это может помочь

// config/horizon.php
...
    'local' => [
        'supervisor-1' => [
            'connection' => 'redis',
            'queue' => ['high', 'default'],
            'balance' => 'false',
            'processes' => 1,
            'tries' => 0
          ,
        ],
    ],
...

Обратите внимание, что с приведенной выше конфигурацией у нас есть два queues specified (высокий, по умолчанию)

У нас также есть balance=false и processes=1

Чтобы лучше понять, какие процессы создаются, мы можем войти на наш сервер Homestead.

  1. Войдите в Усадьбу с homestead ssh. Это работает, только если вы используете усадьбу И вы настраиваете эту функцию.
  2. Находясь на сервере, вы можете запустить top, чтобы просмотреть список всех процессов.

На изображении ниже каждая строка представляет собой процесс на сервере. Я вырезал кучу бесполезной информации типа PID. Здесь вы просто видите команду, которую выполняет Horizon. Если вам интересно, как я получил эту информацию, Посмотрите мой другой пост.

artisan horizon:superviso - это процесс, отвечающий за управление рабочими процессами.

artisan horizon:work - это наш фактический рабочий процесс, созданный supervisor.

Обратите внимание, что supervisor имеет параметр --max-processes=1 и --min-processes=1. Мин-процессы станут более важными с другими стратегиями, о которых мы поговорим позже.

И обратите внимание, что у процесса horizon:work есть параметр --queue=high,default. Это означает, что он сначала обрабатывает ВСЕ высокие задания, а затем задания по умолчанию. Это также изменится в других стратегиях.

Что произойдет, если у меня будет несколько заданий в обеих очередях? В каком порядке они обрабатываются?

У меня есть небольшой сценарий, который создает несколько простых тестовых заданий для обеих очередей, просто чтобы продемонстрировать, что заказы обрабатываются. Давайте взглянем!

  1. Я добавил несколько заданий в очередь - 5 по умолчанию z:1, z:2, z:3, z:4, z:5
    - 1 высокая high1
  2. Очередь начинается с обработки задания с высоким приоритетом (high1), затем задания по умолчанию (z:1)
  3. Когда рабочий начинает обрабатывать z:2, я вручную создал еще 5 заданий по умолчанию и еще 1 задание высокого уровня.
  4. Рабочий закончил обработку z:2, затем приступил к high2 заданию.

Имейте в виду, что в этом примере у меня только один рабочий процесс. Если у меня есть 2 или более рабочих, вы увидите, что одновременно запускаются несколько заданий.

баланс = простой

В документации сказано:

Стратегия simple […] равномерно распределяет входящие задания между процессами.

В случае balance=simple рабочие процессы создаются следующим образом:

  1. Всегда создавайте по 1 рабочему процессу для каждой очереди, даже если вы указали меньше processes, чем очередей в вашей конфигурации.
  2. Если остались какие-либо оставшиеся процессы, создайте по 1 новому процессу для каждой очереди в том порядке, в котором очереди указаны в конфигурации.

Например:

'queue' => ['high', 'default'],
'balance' => 'simple',
'processes' => 1,

приведет к 2 процессам, НЕ 1 процессу. Для каждой очереди в конфигурации queue создается 1 процесс.

А это:

'queue' => ['high', 'default', 'emails'],
'balance' => 'simple',
'processes' => 5,

приведет к общему количеству 5.

  • 2 для high
  • 2 для default
  • 1 для emails

Почему это важно? Представьте, что вы хотите, чтобы ваши работы сначала обрабатывали все, что находится в очереди high приоритета, прежде чем переходить в очередь default. В таком случае придерживайтесь balance=false

баланс = авто

В документации сказано:

Стратегия auto регулирует количество рабочих процессов в очереди на основе текущей рабочей нагрузки очереди. Например, если ваша очередь notifications имеет 1000 ожидающих заданий, а ваша очередь render пуста, Horizon будет выделять больше работников в вашу очередь notifications, пока она не станет пустой.

В случае balance=auto рабочие процессы создаются следующим образом:

  1. Всегда создавайте по одному рабочему процессу для каждой очереди, даже если вы указали меньше processes, чем очередей в вашей конфигурации.
  2. Если остались какие-либо оставшиеся процессы, создайте по 1 новому процессу для каждой очереди в том порядке, в котором очереди указаны в конфигурации.
  3. Затем рабочие процессы переназначаются в разные очереди в зависимости от того, в какой из них есть задания. В очереди всегда будет хотя бы 1 процесс.

Например:

'queue' => ['high', 'default'],
'balance' => 'auto',
'processes' => 1,

приведет к 2 процессам, а НЕ 1 процессу. Для каждой очереди в конфигурации queue создается 1 процесс.

А это:

'queue' => ['high', 'default', 'emails'],
'balance' => 'auto',
'processes' => 5,

приведет к общему количеству 5.

  • 2 для high
  • 2 для default
  • 1 для emails

Однако 2 рабочих будут переназначены в ту очередь, в которой больше всего заданий. Например, если в emailsqueue 1000 заданий, в очереди high 0 заданий, а в defaultqueue 10 заданий, Horizon вы, вероятно, переназначите рабочих следующим образом:

  • 1 для high
  • 1 для default
  • 3 для emails

Обратите внимание, что в очереди с приоритетом high все еще есть 1 работник, хотя для этой очереди 0 заданий.

Вот еще один пример: у нас будет 2 очереди и 6 процессов. Мы добавляем 1000 заданий в default очередь, а затем через минуту добавляем 1000 high приоритетных заданий и смотрим, как Horizon переназначает рабочих в очереди с большим количеством заданий.

'queue' => ['high', 'default'],
'balance' => 'auto',
'processes' => 6,

После добавления 1000 default рабочих мест:

После добавления 1000 high вакансий, когда есть еще 980 default вакансий:

Примечание. Функция balance=auto не будет выполнять автоматическое переключение, если у вас не будет избытка processes. Если у вас 10 очередей и 11 процессов, 1 рабочий процесс сможет свободно перемещаться между очередями.

И в simple, и в auto: Если вы настроите 10 очередей и установите для своих процессов 1, у вас фактически будет запущено 10 процессов. Даже если вы установите для своих процессов 9, у вас все равно будет 10 запущенных, по 1 для каждой очереди.

Если вам интересно, как я пришел к таким выводам, ознакомьтесь с моим другим постом, в котором представлены случайные заметки о том, как я тестирую каждый случай.

Могу ли я изменить min-процессы?

Если вы похожи на меня, вы можете подумать, что min-processes - это просто параметр конфигурации в команде горизонта. Могу ли я изменить это и изменить способ создания моих рабочих в Horizon. В вашем config/horizon.php вы можете добавить это в конфигурацию:

'min-processes' => 0

Или это:

'min-processes' => '5',

Команда горизонта обновляется для использования этой конфигурации, однако, похоже, она не оказывает никакого влияния на то, как порождаются процессы.