Настройка фоновых задач: Sidekiq, Celery, Bull
Фоновые задачи вынесены из HTTP-цикла: пользователь не ждёт завершения операции. Выбор инструмента зависит от стека: Sidekiq — Ruby/Rails, Celery — Python/Django/FastAPI, Bull/BullMQ — Node.js.
Sidekiq (Ruby/Rails)
Sidekiq использует Redis как хранилище очереди, поддерживает ретраи, мертвые задачи, планировщик.
# Gemfile
gem 'sidekiq', '~> 7.0'
gem 'sidekiq-scheduler'
# config/sidekiq.yml
:concurrency: 10
:queues:
- [critical, 5]
- [default, 3]
- [mailers, 2]
- [low, 1]
# app/workers/email_worker.rb
class EmailWorker
include Sidekiq::Job
sidekiq_options queue: :mailers, retry: 3, backtrace: true
def perform(user_id, template, variables = {})
user = User.find(user_id)
UserMailer.send(template, user, variables).deliver_now
end
end
# Вызов
EmailWorker.perform_async(user.id, :welcome)
EmailWorker.perform_in(5.minutes, user.id, :follow_up)
EmailWorker.perform_at(Time.zone.parse('2024-01-01 09:00'), user.id, :new_year)
Celery (Python/Django)
# celery.py
from celery import Celery
from celery.schedules import crontab
app = Celery('myapp')
app.config_from_object('django.conf:settings', namespace='CELERY')
# settings.py
CELERY_BROKER_URL = 'redis://redis:6379/0'
CELERY_RESULT_BACKEND = 'redis://redis:6379/1'
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_EXPIRES = 3600
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
CELERY_BEAT_SCHEDULE = {
'send-daily-digest': {
'task': 'myapp.tasks.send_daily_digest',
'schedule': crontab(hour=9, minute=0),
},
'cleanup-tokens': {
'task': 'myapp.tasks.cleanup_expired_tokens',
'schedule': crontab(minute=0), # каждый час
},
}
# tasks.py
from celery import shared_task
from myapp.models import User
from myapp.services import send_email
@shared_task(
bind=True,
max_retries=3,
default_retry_delay=60, # секунды перед повтором
queue='emails',
)
def send_welcome_email(self, user_id: int) -> dict:
try:
user = User.objects.get(pk=user_id)
send_email(user.email, 'welcome', {'name': user.first_name})
return {'status': 'sent', 'user_id': user_id}
except Exception as exc:
raise self.retry(exc=exc, countdown=2 ** self.request.retries * 60)
# Вызов
send_welcome_email.delay(user.id)
send_welcome_email.apply_async(args=[user.id], countdown=300) # через 5 минут
# docker-compose: воркеры Celery
celery-worker:
build: .
command: celery -A myapp worker --loglevel=info --concurrency=4 -Q emails,default
depends_on: [redis, db]
environment: *app_env
celery-beat:
build: .
command: celery -A myapp beat --loglevel=info --scheduler django_celery_beat.schedulers:DatabaseScheduler
depends_on: [redis, db]
celery-flower:
build: .
command: celery -A myapp flower --port=5555 --basic-auth=admin:password
ports:
- "5555:5555"
BullMQ (Node.js)
Описание в отдельной статье. Краткое сравнение:
| Характеристика | Sidekiq | Celery | BullMQ |
|---|---|---|---|
| Язык | Ruby | Python | Node.js |
| Брокер | Redis | Redis/RabbitMQ/SQS | Redis |
| Concurrency | Threads | Processes/Threads/Gevent | Async/Worker threads |
| UI мониторинг | Sidekiq Web | Flower | BullBoard |
| Планировщик | sidekiq-scheduler | celery-beat | Built-in repeat |
| Реальный приоритет | Да (queues) | Да | Да |
Мониторинг Sidekiq
# config/routes.rb
require 'sidekiq/web'
authenticate :user, ->(u) { u.admin? } do
mount Sidekiq::Web => '/sidekiq'
end
Flower для Celery доступен на порту 5555. Показывает задачи, воркеры, задержки, ретраи.
Срок реализации
Sidekiq или Celery для Django/Rails с базовыми задачами и мониторингом: 2–3 дня. С планировщиком beat, мониторингом и alerting: 3–4 дня.







