Laravel Горизонт: несколько экземпляров на одном сервере мешают друг другу - PullRequest
0 голосов
/ 17 марта 2020

У меня 3 Laravel приложений, работающих на одном сервере, которые нужно использовать для Horizon.

У меня возникла проблема, из-за которой приложения, в которых конфликты и задания не запускались.

После проверки базы данных Redis с помощью Medis я увидел, что для каждой работы будет 3 записи:

  • PRODUCTION_horizon: 2
  • STAGING_horizon: 2
  • HRS_horizon: 2

Где production, staging и hrs - имена моих приложений, а 2 - идентификатор задания.

Если задание было отправлено с staging он все еще может быть подхвачен production или hrs, а затем просто сидеть в ожидании постановки, фактически никогда не запускаться.

После долгих поисков я нашел способ обойти это добавив префикс ко всем моим очередям с именем приложения.

Таким образом, моя конфигурация изменилась с этого:

        'production' => [
            'default' => [
                'connection' => 'redis',
                'queue' => ['default', 'emails', 'calculations'],
                'balance' => 'simple',
                'processes' => 10,
                'tries' => 1,
            ],
            'long_running' => [
                'connection' => 'redis',
                'queue' => ['bulk_calculations', 'imports', 'build_parents'],
                'balance' => 'simple',
                'processes' => 1,
                'tries' => 3,
                'timeout' => 86400 // 1 day
            ]
        ],
        'staging' => [
            'default' => [
                'connection' => 'redis',
                'queue' => ['default', 'emails', 'calculations'],
                'balance' => 'simple',
                'processes' => 10,
                'tries' => 1,
            ],
            'long_running' => [
                'connection' => 'redis',
                'queue' => ['bulk_calculations', 'imports', 'build_parents'],
                'balance' => 'simple',
                'processes' => 1,
                'tries' => 3,
                'timeout' => 86400 // 1 day
            ]
        ],
        'hrs' => [
            'default' => [
                'connection' => 'redis',
                'queue' => ['default', 'emails', 'calculations'],
                'balance' => 'simple',
                'processes' => 10,
                'tries' => 1,
            ],
            'long_running' => [
                'connection' => 'redis',
                'queue' => ['bulk_calculations', 'imports', 'build_parents'],
                'balance' => 'simple',
                'processes' => 1,
                'tries' => 3,
                'timeout' => 86400 // 1 day
            ]
        ],

На это:

'production' => [
            env('APP_NAME') . '_default' => [
                'connection' => 'redis',
                'queue' => [
                    env('APP_NAME') . '_default',
                    env('APP_NAME') . '_emails',
                    env('APP_NAME') . '_calculations'
                ],
                'balance' => 'simple',
                'processes' => 10,
                'tries' => 1,
            ],
            env('APP_NAME') . '_long_running' => [
                'connection' => 'redis',
                'queue' => [
                    env('APP_NAME') . '_bulk_calculations',
                    env('APP_NAME') . '_imports',
                    env('APP_NAME') . '_build_parents'
                ],
                'balance' => 'simple',
                'processes' => 1,
                'tries' => 3,
                'timeout' => 86400 // 1 day
            ]
        ],
        'staging' => [
            env('APP_NAME') . '_default' => [
                'connection' => 'redis',
                'queue' => [
                    env('APP_NAME') . '_default',
                    env('APP_NAME') . '_emails',
                    env('APP_NAME') . '_calculations'
                ],
                'balance' => 'simple',
                'processes' => 10,
                'tries' => 1,
            ],
            env('APP_NAME') . '_long_running' => [
                'connection' => 'redis',
                'queue' => [
                    env('APP_NAME') . '_bulk_calculations',
                    env('APP_NAME') . '_imports',
                    env('APP_NAME') . '_build_parents'
                ],
                'balance' => 'simple',
                'processes' => 1,
                'tries' => 3,
                'timeout' => 86400 // 1 day
            ]
        ],
        'hrs' => [
            env('APP_NAME') . '_default' => [
                'connection' => 'redis',
                'queue' => [
                    env('APP_NAME') . '_default',
                    env('APP_NAME') . '_emails',
                    env('APP_NAME') . '_calculations'
                ],
                'balance' => 'simple',
                'processes' => 10,
                'tries' => 1,
            ],
            env('APP_NAME') . '_long_running' => [
                'connection' => 'redis',
                'queue' => [
                    env('APP_NAME') . '_bulk_calculations',
                    env('APP_NAME') . '_imports',
                    env('APP_NAME') . '_build_parents'
                ],
                'balance' => 'simple',
                'processes' => 1,
                'tries' => 3,
                'timeout' => 86400 // 1 day
            ]
        ],

На самом деле все заработало! По сути, я исправил это.

Но это действительно неправильно.

Теперь, когда я отправляю задание в указанную c очередь, мне нужно сделать MyJob::dispatch()->onQueue(config('app.name') . '_emails');

Что, очевидно, не идеально.

Мне кажется, что должен быть лучший способ, но в документах нет ничего, объясняющего, как это сделать.

Есть ли способ остановить вмешательство горизонта в друг с другом? Может быть, мне следует использовать несколько баз данных Redis или что-то в этом роде?

Я понимаю, что может показаться странным задавать вопрос о чем-то, что я уже нашел решение, но я хотел попытаться исправить это сам, прежде чем слепо спросить и хотя я нашел решение, меня действительно раздражает, что, возможно, есть гораздо более простое решение, о котором я просто не знаю. В худшем случае, если нет лучшего решения, кто-то еще с такой же проблемой найдет это и обнаружит мое решение.

1 Ответ

0 голосов
/ 19 марта 2020

На самом деле лучшим решением является использование значений для базы данных REDIS в вашем файле .env

REDIS_DB=2 (default is 0)
REDIS_CACHE_DB=3 (default is 1)

Redis по умолчанию имеет 16 баз данных, поэтому при условии, что на одном сервере установлено максимум 8 сайтов, которые должно быть в порядке.

Я думаю, что вы можете использовать еще больше баз данных, добавив дополнительные записи в redis раздел database.php.

Но я не уверен, что вы положите в Horizon, чтобы использовать их.

Один маленький совет, если вы используете https://github.com/luin/medis, то вы не сможете сразу увидеть другие базы данных, вам нужно go к терминал и используйте select 3 для просмотра третьей базы данных.

...