Celery + Redis: фоновые задачи на VPS
Отправка писем, обработка изображений, отчёты — всё, что тормозит ответ, выносят в фон. Celery с брокером Redis решает это в Python-приложениях. Развернём воркеры и планировщик на VPS как systemd-сервисы.
Содержание
Зачем выносить задачи в фон
['Если пользователь ждёт ответа, пока сервер шлёт письмо или генерирует PDF, UX страдает, а воркеры веб-сервера заняты. Celery принимает задачу в очередь и отдаёт управление мгновенно, а обработка идёт отдельными процессами.', '- Брокер (Redis) — хранит очередь задач.
- Воркеры — процессы, которые забирают и выполняют задачи.
- Beat — планировщик периодических задач (аналог cron внутри приложения).
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.
Арендовать VPS для CeleryУстановка Redis и Celery
['Redis ставим из пакетов и включаем автозапуск. Celery — в виртуальное окружение проекта.', 'sudo apt update && sudo apt install -y redis-server\nsudo systemctl enable --now redis-server\nredis-cli ping # PONG', 'python3 -m venv /var/www/app/venv\nsource /var/www/app/venv/bin/activate\npip install celery[redis]', 'Защитите Redis: он должен слушать только localhost. В /etc/redis/redis.conf проверьте bind 127.0.0.1 и при необходимости задайте requirepass.']
Код приложения
['Минимальныйtasks.py: инстанс Celery с Redis-брокером и одна задача.', 'from celery import Celery\n\napp = Celery(\n "myapp",\n broker="redis://localhost:6379/0",\n backend="redis://localhost:6379/1",\n)\n\n@app.task\ndef send_email(to, subject):\n # долгая операция\n return f"sent to {to}"', 'Вызов задачи из веб-кода не блокирует ответ:', 'from tasks import send_email\nsend_email.delay("user@example.com", "Привет")']
Воркер и beat как systemd-сервисы
['Запускать celery в screen — путь к потерянным задачам после ребута. Оформляем воркер как systemd-юнит/etc/systemd/system/celery.service.', '[Unit]\nDescription=Celery Worker\nAfter=network.target redis-server.service\n\n[Service]\nType=simple\nUser=www-data\nWorkingDirectory=/var/www/app\nExecStart=/var/www/app/venv/bin/celery -A tasks worker \\\n --loglevel=info --concurrency=4\nRestart=always\n\n[Install]\nWantedBy=multi-user.target', 'Планировщик beat — отдельный юнит celery-beat.service с ExecStart=... celery -A tasks beat --loglevel=info. Запускаем оба:', 'sudo systemctl daemon-reload\nsudo systemctl enable --now celery celery-beat\nsudo systemctl status celery']
Периодические задачи и мониторинг
['Расписание для beat задаётся в конфиге Celery черезbeat_schedule:', 'app.conf.beat_schedule = {\n "cleanup-every-hour": {\n "task": "tasks.cleanup",\n "schedule": 3600.0,\n },\n}', 'Для наблюдения за очередью поставьте Flower — веб-панель Celery:', 'pip install flower\ncelery -A tasks flower --port=5555 --address=127.0.0.1', 'Открывайте Flower только через reverse proxy с авторизацией — наружу порт 5555 не публикуйте. Flower показывает реальную нагрузку: сколько задач выполнено и провалено, время обработки, активные воркеры. Это первый инструмент, к которому обращаются, когда задачи «залипают» или очередь растёт.', 'Для надёжности включите подтверждение задач после выполнения через task_acks_late = True и ограничьте время задачи через task_time_limit. Тогда зависшая задача не заблокирует воркер навсегда, а упавший при обработке воркер вернёт задачу в очередь, а не потеряет её.']
Частые ошибки
['- Задачи копятся, не выполняются — воркер не запущен или подключён к другой базе Redis. Проверьте
redis-cli -n 0 llen celery. - Connection refused — Redis не поднят или слушает не тот интерфейс.
- Воркер съел всю память — большие результаты в backend. Ставьте
result_expiresи не храните тяжёлые объекты. - Beat дублирует задачи — запущено несколько экземпляров beat. Он должен быть строго один.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.
Арендовать VPS для CeleryЧастые вопросы
Redis или RabbitMQ для Celery?
Redis проще ставить и достаточно для большинства задач. RabbitMQ выбирают при сложной маршрутизации и требованиях к гарантиям доставки.
Сколько воркеров запускать?
Начните с concurrency равным числу ядер CPU для CPU-bound задач. Для IO-bound задач можно больше или используйте пул gevent/eventlet.
Как не потерять задачи при рестарте?
Включите acks_late и настройте Redis на сохранение данных (AOF), чтобы очередь переживала перезапуск.