Написано на Nest.js
Нужно спроектировать и частично реализовать сервис распределенной обработки фотографий на NestJS.
Основные требования:
- REST API для загрузки фото
- Распределенная очередь задач на Redis:
- Создание превью (маленькое изображение)
- Извлечение EXIF
- Хранение результатов в PostgreSQL
- Возможность масштабирования воркеров
- Документация API (Swagger)
- Покрытие тестами
Продвинутые требования (1-2шт по желанию):
- Отказоустойчивость при падении Redis
- Мониторинг очереди
- Повторная обработка неудачных задач
- Graceful shutdown
- S3-совместимое хранилище
- Метрики производительности
- Повторная обработка неудачных задач
- Мониторинг очереди
Повторная обработка неудачных задач
Для чего это нужно:
- Обеспечение надежности системы:
- В реальной жизни задачи могут завершаться с ошибками из-за временных сбоев (например, потеря связи с Redis, перегрузка сервиса или ошибки сети).
- Повторная обработка позволяет гарантировать, что временные сбои не приведут к потере данных или неудаче в обработке.
- Обработка зависимых данных:
- Например, задача на создание превью может зависеть от сохранения файла на диск или в S3. Если предыдущая задача завершилась сбоем, мы можем повторить её позже и продолжить выполнение цепочки.
- Минимизация ручного вмешательства:
- Без автоматической повторной обработки неудачные задачи потребуют ручного вмешательства от разработчиков или администраторов для исправления, что увеличивает операционные затраты и замедляет работу системы.
- Гарантия корректного результата:
- Даже если сбой произошел, система сможет гарантировать обработку всех задач (например, извлечение EXIF-данных или создание превью для загруженных фотографий).
Как это реализуется:
- Backoff (отложенные повторные попытки): Система может повторять задачу с возрастающим интервалом между попытками.
- Лимит попыток: После определенного количества попыток задача может быть отправлена в специальный "мертвый" список (dead-letter queue) для дальнейшего анализа.
Мониторинг очереди
Для чего это нужно:
- Отслеживание состояния системы:
- Мониторинг позволяет понять, сколько задач в очереди находятся в ожидании, обрабатываются или завершились с ошибками.
- Это важно для оценки производительности системы и выявления узких мест (например, нехватка воркеров).
- Предотвращение накопления задач:
- Если система начинает перегружаться или Redis перестает справляться, мониторинг позволяет заметить аномальное поведение (например, большое количество невыполненных задач) и принять меры (увеличение числа воркеров, балансировка нагрузки).
- Устранение проблем в реальном времени:
- Например, если очередь начинает расти из-за неудачных задач или медленной обработки, администраторы могут оперативно масштабировать количество воркеров или перераспределить задачи.
- Диагностика ошибок:
- Мониторинг помогает увидеть, какие задачи часто завершаются с ошибками, и это упрощает диагностику проблем в коде или инфраструктуре.
- Сбор метрик производительности:
- Сколько времени занимает обработка одной задачи?
- Какие типы задач обрабатываются чаще всего?
- Это важно для анализа и оптимизации системы.
Как это реализуется:
- Использование специализированных инструментов для мониторинга очередей, например:
- BullMQ UI или Bull Board для отслеживания состояния задач.
- Grafana/Prometheus для сбора и отображения метрик Redis и воркеров.
- Настройка логирования и алертов для критических событий (например, превышение времени ожидания задач или высокая нагрузка на очередь).
Эти две функции являются основой для построения надежного, масштабируемого и отказоустойчивого REST API с очередями задач.
$ npm install
Для запуска Postgres и Redis запустить Docker. Чтобы таблицы Бд хранились вне образа (и данные не терялись при перезапуске контейнера) нужно:
Создать папку для данных PostgreSQL:
mkdir -p ./pg_data
Дать ей нужные права, чтобы контейнер мог писать в нее:
chmod -R 777 ./pg_data
И затем запустить контейнеры:
docker-compose up -d
БД тут http://localhost:8080, логин и пароль в docker-compose.yml
Running the app
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.
- Author - Kamil Myśliwiec
- Website - https://nestjs.com
- Twitter - @nestframework
Nest is MIT licensed.