Увійти Реєстрація
Вакансії
Вакансії Laravel Компанії Статистика
Підготовка
Як підготуватися < href="https://laravelukraine.com/interviews" wire:navigate.hover class="flex items-center gap-3 rounded-md px-3 py-2 text-base font-medium text-gray-600 hover:bg-gray-50 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-900 dark:hover:text-white" >Співбесіди Тестування Документація
Блог
Всі статті Серії
Екосистема
Пакети Ресурси Проєкти Інструменти Події Відео
Інше
Про нас Реклама
Переклади 13 листопада 2026

Налаштування Laravel Horizon: що перевірити, коли черги перевантажують сервер

Ми самі хостимо Mailcoach і керуємо його воркерами черг через Laravel Horizon. (Mailcoach - застосунок від Spatie для email-розсилок і автоматизацій на Laravel, - прим. пер.) Щоразу, коли Mailcoach надсилав кампанію, моніторинг повідомляв про високе навантаження на сервер, а сайт сповільнювався. Я також бачив багато активності PHP-FPM, але саме по собі це не пояснювало стрибка. Я почав із того, що звірив конфігурацію воркерів із завданнями, які ми насправді запускаємо.

1. З'ясуйте, хто споживає чергу

  • Складіть список супервізорів Horizon і всіх окремих процесів queue:work.
  • Порівняйте базу даних Redis, префікс ключів і назви черг, якими користується кожен воркер.

Різні назви підключень у Laravel все одно можуть вказувати на ті самі ключі черги в Redis. Якщо в цих підключень різні вікна повторної спроби, один воркер може підхопити завдання, яке інший ще виконує. Завдання, що триває десять хвилин, може запуститися двічі, якщо інший воркер використовує retry_after у 90 секунд.

Перевірте фактичну конфігурацію кожного воркера, що споживає ці черги. Для Mailcoach також порівняйте його налаштування queue_connection з підключенням, яке використовують ваші супервізори Horizon.

2. Залиште запас між timeout завдання і retry_after

  • Перевіряйте timeout на рівні завдань, а також налаштування супервізорів і окремих воркерів.
  • Тримайте timeout супервізора Horizon вищим за timeout завдань і нижчим за retry_after підключення.
  • Використовуйте однаковий retry_after для підключень, що ділять Redis-черги.

Визначайте запас за найдовшими завданнями, які ви очікуєте. Наші завдання мають timeout до десяти хвилин, тож ми обрали щедрі круглі значення нижче. Пам'ятайте про компроміс: довше вікно повторної спроби також затримує відновлення, якщо воркер помре, тримаючи зарезервоване завдання.

// config/queue.php, у кожному Redis-підключенні, яке ділить ці черги
'retry_after' => 60 * 60,

// config/horizon.php, у налаштуваннях відповідного супервізора
'timeout' => 60 * 30,

Додайте тести застосунку, які зловлять зміни конфігурації, що порушують ці співвідношення. Ця перевірка має бути всередині тесту, який проходить циклом по супервізорах Horizon:

$connection = $supervisor['connection'];
$retryAfter = config("queue.connections.{$connection}.retry_after");

$this->assertLessThan($retryAfter, $supervisor['timeout']);

3. Перевірте розгортання і алерти очікування

  • Переконайтеся, що під час розгортання Horizon завершується, а менеджер процесів запускає його знову вже на новому релізі.
  • Зіставте кожен алерт очікування Horizon з реальною парою connection:queue і перевірте, що він до вас доходить.

Додайте php artisan horizon:terminate у своє розгортання і налаштуйте менеджер процесів, який підніматиме Horizon знову. Окремі воркери перевірте окремо.

Для розгортання застосунку я використовую Deployer. З його рецептом для Laravel я додав у deploy.php таке завдання і хук:

task('artisan:horizon:terminate', artisan('horizon:terminate'));
before('deploy:success', 'artisan:horizon:terminate');

Ключі waits у Horizon мають відповідати реальним парам connection:queue. Наприклад, цей ключ позначає чергу send-mail на підключенні mailcoach-redis:

mailcoach-redis:send-mail

Оберіть поріг, що відповідає звичайній поведінці черги, і протестуйте маршрут сповіщень. Враховуйте навмисне обмеження швидкості (throttling): воно впливає на те, скільки завдання чекають. Час очікування в черзі і прогрес кампанії також розповідають різне, тож відстежуйте обидва, якщо вам треба знати, чи робота рухається. Подробиці конфігурації - в документації Laravel Horizon.

4. Вимірюйте, перш ніж змінювати кількість воркерів

Коли конфігурація має сенс, зберіть вимірювання під час реального навантаження. Вони знадобляться, щоб оцінити, чи допоможе зміна кількості воркерів або коригування обмеження швидкості.

Для Mailcoach корисно записувати:

  • навантаження на сервер, доступну пам'ять і використання swap;
  • використання CPU і пам'яті воркерами черг і процесами PHP-FPM;
  • розміри черг поруч із прогресом кампанії;
  • фактичну швидкість надсилання порівняно з вашим обмеженням і лімітами поштового провайдера.

Дивіться на ці показники разом. Черзі, що росте, можуть знадобитися додаткові воркери, але спершу перевірте, чи має сервер для них ресурси. Якщо PHP-FPM зайнятий, а воркери простоюють, дослідіть також вебзапити.

Я додав власну Artisan-команду, яка щохвилини записує ці метрики в лог, поки кампанія надсилається, і ще одну команду, що підсумовує цей лог.

5. Шукайте причину додати воркери

  • Перевірте, чи справді робота накопичується саме в тій черзі, яку ви налаштовуєте.
  • Порівняйте фактичну швидкість надсилання з вашим обмеженням і лімітом провайдера.
  • Порівняйте активність воркерів і PHP-FPM у моменти стрибків навантаження.

Перш ніж збільшувати кількість воркерів черги, перевірте, що на ній виконується. Одночасно працює лише один диспетчер кампаній Mailcoach. Другий воркер дає змогу завданням автоматизацій у тій самій черзі виконуватися, поки диспетчер зайнятий. Окремі листи йдуть через окрему чергу, тож додавання воркерів для диспетчера потребує власного обґрунтування.

Я виміряв близько 0,55 листа на секунду при обмеженні в один лист на секунду. Якщо побачу цей розрив знову, то перевірю ліміт надсилання SES, перш ніж чіпати обмеження.

Візьміть показовий запуск за базову лінію, внесіть цілеспрямовану зміну і порівняйте ті самі вимірювання під час наступного запуску. Переглядайте налаштування, коли змінюються тривалість завдань, трафік та інші навантаження на сервері.

Моніторинг налаштовано. Тепер я чекаю наступної кампанії, щоб побачити, як воркери поводяться під навантаженням. Ці вимірювання допоможуть вирішити, що змінити і чи допоможе це на кампанії після неї.

Поки що в мене є конфігурація, яку я можу пояснити, і спосіб перевірити, чи вона відповідає навантаженню.

Читайте також

Переклад оригіналу: standaniels.nl
10

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Читайте також

Переклади 14 листопада 2026

Голод сильніший за стаж: поради junior-інженерам від менеджера Anthropic

Фелікс Різеберг, engineering-менеджер в Anthropic, відмовився від технічних співбесід з кодуванням і пояснює, чому в епоху AI новачки обганяють досвідчених колег - і що конкретно їм робити, щоб їх помітили.

12
OAuth refresh-токен
Переклади 13 листопада 2026

Гонка при оновленні OAuth refresh-токена в Laravel: звідки береться invalid_grant

Кілька воркерів черги одночасно оновлюють той самий OAuth-токен, і провайдер з ротацією refresh-токенів відповідає invalid_grant або взагалі відкликає підключення. Переказ статті Куанга Данга про те, як це розпізнати в логах і виправити через Cache::lock, повторне читання та compare-and-swap.

13

Вакансії за темою

Full Stack Developer (PHP / React) Middle / Middle+

Full Stack розробник розвиватиме та підтримуватиме власний аналітичний продукт для перевірки контрагентів і оцінки ризиків, працюючи зі складною бізнес-логікою та великими обсягами даних. Основний стек: PHP 8.x, Laravel або Symfony, MySQL, React; також потрібні проєктування API, оптимізація SQL-запитів, Docker, CI/CD. Вимоги: комерційний досвід від 3 років, досвід підтримки legacy-коду, англійська B1+ для читання документації.

Repalm
4 дні тому

Senior PHP developer

Senior PHP-розробник для продуктової команди: розробка функціоналу на Laravel, робота з Eloquent ORM, чергами, авторизацією та REST API, а також з MariaDB/MySQL і Redis. Потрібно від 5 років досвіду на PHP, знання JavaScript (jQuery, Ajax), WebSockets, MVC та OOP. Важливі менторство молодших колег, виявлення ризиків і комунікація з продукт-овнерами.

Real Estate Bees
9 днів тому

Backend Engineer (PHP/Laravel)

Розробник бекенду для revenue-критичних систем: проєктування й підтримка REST API для кількох споживачів, реалізація бізнес-логіки, інтеграції з платіжними та партнерськими сервісами, фонові задачі на Redis-чергах і оптимізація великих таблиць PostgreSQL. Стек: API-only Laravel 12 / PHP 8.2, PostgreSQL, поступова міграція до DDD. Вимоги: 3+ роки PHP і production Laravel, досвід роботи з легасі-кодом, тестування, Docker, активне використання AI-інструментів для розробки, англійська intermediate.

Пакети за темою

Kalimera

welldigit/kalimera

Interactive installer that scaffolds Laravel applications the Well Digit way.

v1.0.0 17

Bagisto

bagisto/bagisto

Bagisto — це платформа для електронної комерції, побудована на Laravel. Вона надає готове рішення для створення та управління інтернет-магазинами з підтримкою каталогу товарів, замовлень, платежів та клієнтів.

28,369 v2.5.1 13 28