Що таке Laravel Queue та навіщо воно потрібне?
Laravel Queue – це система черг для виконання тривалих завдань у фоновому режимі. Замість того, щоб користувач чекав поки відправиться email або обробиться велика кількість даних, ці завдання додаються в чергу і виконуються незалежно від веб-запиту.
Приклади використання черг:
- Відправка email повідомлень
- Обробка зображень (зміна розміру, оптимізація)
- Генерація звітів
- Синхронізація з зовнішніми API
- Бекапи та очищення даних
- Відправка push-нотифікацій
Без черги:
|
1 2 3 4 5 6 7 |
public function sendWelcomeEmail(User $user) { // Користувач чекає поки відправиться email Mail::to($user)->send(new WelcomeEmail()); return response()->json(['status' => 'sent']); // Відповідь через 3-5 секунд } |
З чергою:
|
1 2 3 4 5 6 7 |
public function sendWelcomeEmail(User $user) { // Email додається в чергу і відправляється у фоні Mail::to($user)->queue(new WelcomeEmail()); return response()->json(['status' => 'queued']); // Миттєва відповідь } |
Що таке Systemd?
Systemd – це система ініціалізації Linux, яка управляє системними сервісами. Вона автоматично:
- Запускає сервіси при завантаженні системи
- Перезапускає сервіси якщо вони падають
- Логує роботу сервісів
- Дозволяє керувати сервісами (старт/стоп/перезапуск)
Чому не php artisan queue:work в терміналі?
Коли ви закриваєте термінал – процес queue:work зупиняється. Systemd вирішує цю проблему, роблячи queue worker системним сервісом.
Створення Systemd сервісу для Laravel Queue
Крок 1: Створити конфігураційний файл
|
1 2 |
sudo nano /etc/systemd/system/laravel-queue.service |
Базовий приклад сервісу:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[Unit] Description=Laravel Queue Worker After=network.target mysql.service redis.service Requires=mysql.service Wants=redis.service [Service] Type=simple User=www-data Group=www-data Restart=always RestartSec=3 ExecStart=/usr/bin/php /var/www/your-project/artisan queue:work --sleep=3 --tries=3 --max-time=3600 WorkingDirectory=/var/www/your-project StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target |
Розбір параметрів:
[Unit] секція:
Description– опис сервісуAfter– запускати після мережі та баз данихRequires– обов’язкові залежності (MySQL)Wants– бажані залежності (Redis)
[Service] секція:
Type=simple– простий тип сервісуUser/Group=www-data– від якого користувача запускатиRestart=always– завжди перезапускати при падінніRestartSec=3– пауза 3 секунди перед перезапускомExecStart– команда для запускуWorkingDirectory– робоча директоріяStandardOutput/Error=journal– логувати в systemd journal
[Install] секція:
WantedBy=multi-user.target– в якому режимі активувати
Крок 2: Активувати сервіс
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# Перезавантажити systemd конфігурацію sudo systemctl daemon-reload # Увімкнути автозапуск sudo systemctl enable laravel-queue # Запустити сервіс sudo systemctl start laravel-queue # Перевірити статус sudo systemctl status laravel-queue |
Продвинута конфігурація
Множинні черги з різними пріоритетами:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# /etc/systemd/system/laravel-queue-high.service [Unit] Description=Laravel Queue Worker (High Priority) After=network.target mysql.service [Service] Type=simple User=www-data Group=www-data Restart=always RestartSec=3 ExecStart=/usr/bin/php /var/www/project/artisan queue:work --queue=high --sleep=1 --tries=3 [Install] WantedBy=multi-user.target |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# /etc/systemd/system/laravel-queue-low.service [Unit] Description=Laravel Queue Worker (Low Priority) After=network.target mysql.service [Service] Type=simple User=www-data Group=www-data Restart=always RestartSec=5 ExecStart=/usr/bin/php /var/www/project/artisan queue:work --queue=low --sleep=5 --tries=1 [Install] WantedBy=multi-user.target |
Шаблони сервісів для масштабування:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# /etc/systemd/system/laravel-queue@.service [Unit] Description=Laravel Queue Worker %i After=network.target mysql.service [Service] Type=simple User=www-data Group=www-data Restart=always RestartSec=3 ExecStart=/usr/bin/php /var/www/project/artisan queue:work --sleep=3 --tries=3 --name=worker-%i WorkingDirectory=/var/www/project [Install] WantedBy=multi-user.target |
Запуск кількох воркерів:
|
1 2 3 4 5 6 7 |
# Запустити 3 воркери sudo systemctl enable laravel-queue@1 sudo systemctl enable laravel-queue@2 sudo systemctl enable laravel-queue@3 sudo systemctl start laravel-queue@{1..3} |
Environment змінні та секрети:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[Service] Type=simple User=www-data Group=www-data Restart=always # Environment файли EnvironmentFile=/var/www/project/.env EnvironmentFile=-/etc/laravel/secrets.env # Або прямо в сервісі Environment=APP_ENV=production Environment=QUEUE_CONNECTION=redis ExecStart=/usr/bin/php /var/www/project/artisan queue:work # Обмеження ресурсів MemoryMax=512M CPUQuota=50% |
Управління та моніторинг
Основні команди:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Статус сервісу sudo systemctl status laravel-queue # Запуск/зупинка sudo systemctl start laravel-queue sudo systemctl stop laravel-queue sudo systemctl restart laravel-queue # Автозапуск sudo systemctl enable laravel-queue sudo systemctl disable laravel-queue # Перезавантажити конфігурацію після змін sudo systemctl daemon-reload |
Перегляд логів:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# Логи сервісу sudo journalctl -u laravel-queue # Логи в реальному часі sudo journalctl -u laravel-queue -f # Логи за сьогодні sudo journalctl -u laravel-queue --since today # Останні 100 рядків sudo journalctl -u laravel-queue -n 100 |
Моніторинг через Laravel
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// В Laravel додайте middleware для моніторингу черг php artisan make:command MonitorQueues // app/Console/Commands/MonitorQueues.php public function handle() { $size = Queue::size(); $failed = DB::table('failed_jobs')->count(); if ($size > 1000) { Log::alert("Queue size is too high: {$size}"); } if ($failed > 10) { Log::alert("Too many failed jobs: {$failed}"); } } |
Додати в cron для регулярного моніторингу:
|
1 2 3 |
# crontab -e */5 * * * * /usr/bin/php /var/www/project/artisan monitor:queues |
Troubleshooting та кращі практики
Типові проблеми:
1. Сервіс не запускається:
|
1 2 3 4 5 6 |
# Перевірити синтаксис sudo systemd-analyze verify laravel-queue.service # Детальні логи sudo journalctl -u laravel-queue --no-pager |
2. Воркер зависає:
|
1 2 3 4 5 6 7 8 |
[Service] # Додати timeout для зависання TimeoutStartSec=60 TimeoutStopSec=30 # Автоматичний restart кожні 8 годин RuntimeMaxSec=28800 |
3. Проблеми з правами:
|
1 2 3 4 |
# Перевірити права на файли ls -la /var/www/project/storage/ sudo chown -R www-data:www-data /var/www/project/storage/ |
Кращі практики:
1. Graceful shutdown:
|
1 2 3 4 5 6 7 |
[Service] ExecStart=/usr/bin/php /var/www/project/artisan queue:work --stop-when-empty ExecReload=/bin/kill -USR2 $MAINPID KillMode=mixed KillSignal=SIGTERM TimeoutStopSec=30 |
2. Health checks:
|
1 2 3 4 5 6 7 8 |
# Додати health check скрипт # /usr/local/bin/laravel-queue-health.sh #!/bin/bash if ! systemctl is-active --quiet laravel-queue; then echo "Queue service is down!" systemctl restart laravel-queue fi |
3. Логування:
|
1 2 3 4 5 6 |
[Service] # Structured logging StandardOutput=journal StandardError=journal SyslogIdentifier=laravel-queue |
Альтернативи та порівняння
Supervisor vs Systemd
Supervisor:
|
1 2 3 4 5 6 7 8 |
[program:laravel-queue] process_name=%(program_name)s_%(process_num)02d command=php /var/www/project/artisan queue:work autostart=true autorestart=true user=www-data numprocs=4 |
Переваги Systemd:
- Інтеграція з системою логування
- Кращі можливості для dependency management
- Стандартний інструмент Linux
- Автоматичні restart policies
Переваги Supervisor:
- Простіша конфігурація
- Web-інтерфейс для моніторингу
- Кращий контроль множинних процесів
Docker подхід:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# docker-compose.yml version: '3' services: queue: image: your-app command: php artisan queue:work --sleep=3 --tries=3 restart: unless-stopped depends_on: - redis - mysql volumes: - ./:/var/www |
Висновок
Systemd сервіси для Laravel Queue забезпечують:
- Автоматичний запуск при завантаженні системи
- Стійкість до збоїв через auto-restart
- Централізоване логування
- Простоте управління через systemctl
- Інтеграцію з системою безпеки Linux
Для production середовища це найкращий спосіб забезпечити надійну роботу черг Laravel без додаткових залежностей типу Supervisor.
Швидкий checklist:
- Створити .service файл з правильними параметрами
- Встановити правильного користувача (www-data)
- Налаштувати restart policy
- Додати залежності (MySQL, Redis)
- Увімкнути автозапуск
- Налаштувати моніторинг через журнали
- Перевірити performance та ресурси
Systemd надає професійний рівень керування процесами для Laravel додатків у production.