Налаштування Redis для реалізації черг завдань

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

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

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Налаштування Redis для реалізації черг завдань
Середня
від 1 робочого дня до 3 робочих днів
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Налаштування Redis для реалізації очередей завдань

Очереди завдань потрібні там, де операція занадто довгаяДля HTTP-запиту: відправка email, генерація PDF, обробка зображень, синхронізація з зовнішніми API. Замість синхронного виконання та утримання з'єднання, завдання ставиться в очередь Redis та виконується воркером у фоні. Користувач отримує відповідь негайно.

Структури даних Redis для очередей

Redis підтримує кілька підходів до реалізації очередей:

List + LPUSH/RPOP (FIFO) — найпростіший. LPUSH queue task додає в голову, RPOP queue забирає з хвоста. Проблема: воркер в циклі робить RPOP — якщо очередь пустаяЧ витрачає CPU на пусті запити.

BLPOP (Blocking List Pop) — RPOP з блокуванням: воркер чекає появи завдання без polling:

BLPOP queue1 queue2 0  # 0 = чекати нескінченно
# При появленні завдання повертає [queue_name, value]

Sorted Set для відкладених завдань — завдання з часом виконання зберігаються в sorted set з score = timestamp:

ZADD delayed_queue 1704067200 "task_payload"  # Unix timestamp
# Воркер періодично перевіряє:
ZRANGEBYSCORE delayed_queue 0 NOW LIMIT 0 10
ZREM delayed_queue "task_payload"

Redis Streams — більш потужний механізм з групами консьюмерів, підтвердженнями (ACK), replay. Рекомендується для серйозних production-систем.

Laravel Queue з Redis

Laravel Queue — абстракція поверх різних backend'ів. Redis — один з кращих варіантів: швидкий, підтримує приоритети, delayed jobs, failed jobs.

config/queue.php:

'default' => env('QUEUE_CONNECTION', 'redis'),

'connections' => [
    'redis' => [
        'driver' => 'redis',
        'connection' => 'queue',
        'queue' => env('REDIS_QUEUE', 'default'),
        'retry_after' => 90,  // Секунди до повторної попитки якщо воркер упав
        'block_for' => 5,     // Секунди блокування BLPOP
        'after_commit' => true, // Ставити в очередь після комміту транзакції
    ],
],

config/database.php — окреме Redis підключення для очередей:

'queue' => [
    'host' => env('REDIS_QUEUE_HOST', '127.0.0.1'),
    'password' => env('REDIS_QUEUE_PASSWORD'),
    'port' => env('REDIS_QUEUE_PORT', '6379'),
    'database' => env('REDIS_QUEUE_DB', '2'),
    'read_timeout' => 60,
],

Створення Job:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SendOrderConfirmationEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 3;
    public int $timeout = 60;
    public int $backoff = 30; // Секунди між повторними спробами

    public function __construct(
        private readonly int $orderId
    ) {}

    public function handle(OrderRepository $orders, Mailer $mailer): void
    {
        $order = $orders->findWithItems($this->orderId);
        $mailer->to($order->customer_email)
               ->send(new OrderConfirmation($order));
    }

    public function failed(\Throwable $exception): void
    {
        // Сповістити команду про провал
        \Log::error('Order confirmation email failed', [
            'order_id' => $this->orderId,
            'error' => $exception->getMessage(),
        ]);
    }
}

Постановка в очередь:

// Негайно
SendOrderConfirmationEmail::dispatch($order->id);

// З затримкою (5 хвилин)
SendOrderConfirmationEmail::dispatch($order->id)->delay(now()->addMinutes(5));

// У конкретну очередь
SendOrderConfirmationEmail::dispatch($order->id)->onQueue('emails');

// Ланцюжок завдань (виконуються послідовно)
ProcessImage::withChain([
    new GenerateThumbnails($imageId),
    new SendNotification($userId),
])->dispatch($imageId);

Запуск воркерів

# Один воркер, очередь 'default'
php artisan queue:work redis --queue=default --sleep=3 --tries=3

# Кілька очередей з приоритетами
php artisan queue:work redis --queue=critical,high,default --timeout=60

# Daemon режим (не перезапускає PHP між завданнями — швидше)
php artisan queue:work --daemon

# Після деплою нового кода — перезапустити воркери
php artisan queue:restart

Supervisor для управління воркерами в production:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/myapp/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=4
redirect_stderr=true
stdout_logfile=/var/log/worker.log
stopwaitsecs=3600

numprocs=4 — чотири паралельні воркери. Для IO-інтенсивних завдань (email, API calls) можна більше. Для CPU-інтенсивних (обробка зображень) — не більше ядер.

Моніторинг очередей

Laravel Horizon — офіційний dashboard для моніторингу Redis Queue:

composer require laravel/horizon
php artisan horizon:install

config/horizon.php:

'environments' => [
    'production' => [
        'supervisor-1' => [
            'maxProcesses' => 10,
            'balanceMaxShift' => 1,
            'balanceCooldown' => 3,
            'queue' => ['critical', 'default', 'emails'],
            'balance' => 'auto',  // Автоматично розподіляти процеси по очередях
            'minProcesses' => 1,
            'tries' => 3,
            'timeout' => 60,
        ],
    ],
],

Запуск:

php artisan horizon

Horizon автоматично керує числом воркерів під навантаженням та відображає метрики: throughput, failed jobs, wait time.

Failed Jobs

Провальні завдання зберігаються в Redis (або БД). Перегляд та повторний запуск:

# Список провальних завдань
php artisan queue:failed

# Повторити конкретне завдання
php artisan queue:retry 5

# Повторити всі провальні
php artisan queue:retry all

# Видалити провальні
php artisan queue:flush

Таймлайн

Базова настройка Laravel Queue з Redis та Supervisor — 1 робочий день. Додавання Horizon з моніторингом та auto-scaling — ще половина дня. Реалізація складних ланцюжків завдань з retry-логікою та алертами на failed jobs — 1–2 дні.