Кейс: генерация отчётов и тяжёлые фоновые задачи
↑ 8.4 Backend System Design · ← Предыдущая · → Следующая
Зачем это на собесе
Как проектировать долгие операции, не блокируя API.
Объяснение
Требования: пользователь запрашивает отчёт (часто минуты и гигабайты данных), система не должна падать от пиков, нужен статус выполнения, отмена, история, безопасная выдача результата.
flowchart LR U[Клиент] -->|POST /reports| API API -->|задача| DB[(reports: status)] API -->|событие| QОчередь API -->|202 + id| U Q --> W[Воркеры отчётов] W --> SRC[(Реплика БД / ClickHouse)] W --> S3[(MinIO)] W --> DB U -->|GET /reports/id| API API -->|pre-signed URL| U
Решения:
| Вопрос | Решение |
|---|---|
| Асинхронность | POST → 202 Accepted + Location; клиент опрашивает или получает уведомление |
| Очередь | брокер, приоритеты, ограничение параллелизма |
| Изоляция | отдельные воркеры и реплика/OLAP-источник: OLTP не страдает |
| Надёжность | статусы в БД (queued/running/done/failed), повтор при падении воркера, идемпотентный ключ |
| Большие данные | потоковая генерация, чанки, файлы в объектное хранилище, а не в память |
| Отмена/таймаут | CancellationToken, дедлайн задачи |
| Выдача | pre-signed URL со сроком действия, права доступа |
| Кэш | одинаковые параметры → готовый результат (по хэшу параметров) |
| Справедливость | лимит задач на пользователя/тенанта, приоритеты |
| Очистка | TTL файлов отчётов |
| Наблюдаемость | длительность, длина очереди, доля ошибок |
Идентификация «зависших» задач: heartbeat воркера и повторная постановка при его пропадании.
Нюансы и подводные камни
- Тяжёлые запросы к основной БД замедляют весь сервис.
- Потеря задач при перезапуске воркера без подтверждения.
- Пользователь запускает один отчёт много раз: дедупликация.
- Неограниченный размер результата: лимиты и предупреждения.
- Утечка данных через публичные ссылки на файлы.
Практика
- Реализуйте асинхронный API отчётов со статусами и pre-signed URL.
- Добавьте heartbeat и повторную постановку зависших задач.
- Ограничьте параллелизм и объём на пользователя.
Вопросы с ответами
Почему отчёт нельзя строить в HTTP-запросе?
Долго и ресурсоёмко: таймауты, блокировка потоков, нестабильность; лучше очередь и асинхронный статус.
Как не потерять задачу при падении воркера?
Статус в БД и подтверждение обработки в брокере после завершения, повторная постановка по heartbeat.