https://github.com/azhvanko/final_price
https://github.com/azhvanko/final_price
docker docker-compose fastapi gunicorn postgresql python rq
Last synced: 3 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/azhvanko/final_price
- Owner: azhvanko
- License: gpl-3.0
- Created: 2025-10-05T11:27:44.000Z (9 months ago)
- Default Branch: master
- Last Pushed: 2025-10-06T05:56:27.000Z (9 months ago)
- Last Synced: 2025-10-06T07:28:32.812Z (9 months ago)
- Topics: docker, docker-compose, fastapi, gunicorn, postgresql, python, rq
- Language: Python
- Homepage:
- Size: 191 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# FinalPrice
### Техническое задание: Разработка прототипа высоконагруженной системы сбора заказов
#### Назначение
Прототип одностраничного веб-приложения для сбора предзаказов в рамках краткосрочной акции (например, Black Friday).
Основная задача — гарантированный сбор контактных данных (имя, телефон) в условиях пиковых нагрузок с предоставлением пользователю обратной связи
#### Ограничения
* **Нагрузки:** Система должна выдерживать резкие всплески одновременных запросов
* **Производительность БД:** Традиционный подход с долгой обработкой запроса не подходит из-за риска исчерпания пула соединений БД
* **Веб-слой:** Валидация и постановка в очередь; длительные операции — асинхронно
#### Функциональные требования
* **Frontend:** Одна страница с формой для ввода имени и телефона, кнопка отправки. Минимум клиентской логики
* **Backend:**
- Принять и провалидировать данные из формы
- Поместить заявку в устойчивую очередь для последующей обработки
- Пользователю отправляется сообщение «Ваш заказ принят», только после подтвержденного сохранения его данных в базе данных
- В случае ошибки валидации или сбоя записи вернуть соответствующую ошибку
#### Нефункциональные требования
* **Доступность и надёжность:** Гарантированная запись данных даже при высоких нагрузках
* **Производительность и масштабирование:** Архитектура должна обеспечивать быстрое освобождение сетевых соединений и поддерживать горизонтальное масштабирование веб-слоя и воркеров
#### Итоговые материалы
* **Исходный код:** Frontend, API-сервер (backend), Worker service
* **`docker-compose.yml`:** Конфигурация для запуска веб-сервера, воркера и базы данных
* **`README.md`:** Инструкции по локальному запуску и проверке; обоснование выбора технологий и архитектурных решений
* **Рекомендации по эксплуатации в production среде:** Документ с рекомендациями по подготовке системы к промышленной эксплуатации
### Локальный запуск
#### 1. Конфигурация (Опционально)
Перед первым запуском можно внести корректировки в следующих файлах:
* **`.env`**: Файл содержит переменные окружения
* **`docker-compose.yml`**: Может потребоваться изменить внешние порты (`ports`), настройки деплоя (`deploy`)
#### 2. Запуск и остановка
Проект использует `Makefile` для упрощения управления контейнерами
* **Запуск.** Сборка docker образов и запуск всех сервисов в фоновом режиме
```bash
make up
```
* **Инициализация базы данных.** Создание таблиц в базе данных
```bash
make migrate
```
* **Создание пользователей.** Создание пользователей по умолчанию
```bash
make create_default_users
```
* **Остановка.** Остановка и удаление docker контейнеров
```bash
make down
```
* **Очистка.** Удаление всех ранее созданных ресурсов
```bash
make clear
```
### Выбор стека технологий
Архитектура прототипа основана на разделении ответственности между компонентами для достижения высокой производительности и отказоустойчивости
* **FastAPI (Backend Framework):**
Выбран за его высокую производительность, по сравнению с другими Python веб-фреймворками
* **PostgreSQL (База данных):**
Надёжная, ACID-совместимая реляционная СУБД. Гарантирует целостность и сохранность данных о заказах, что является ключевым требованием
* **Redis (Брокер сообщений):**
Высокопроизводительное in-memory хранилище с минимальной задержкой при постановке задач в очередь, что позволяет веб-слою мгновенно освобождать соединения и не блокироваться на операциях записи
* **RQ (Библиотека для работы с очередями):**
Простая и легковесная Python-библиотека для организации фонового выполнения задач. Её бесшовная интеграция с Redis делает её идеальным выбором для данного прототипа, позволяя быстро реализовать асинхронную архитектуру с воркерами
### Рекомендации по эксплуатации в production среде
#### 1. Контейнеризация и оркестрация
* В production среде для каждого контейнера (FastAPI, RQ worker) необходимо выставить лимиты на использование CPU, памяти и количество одновременно поднятых реплик
#### 2. Инфраструктура и развёртывание
* Развёртывание приложения оптимально сделать с помощью систем оркестрации контейнеров, таких как Kubernetes или AWS ECS, для автоматизации управления и автоматического масштабирования
* Раздачу статики можно настроить с помощью Nginx. Для максимальной производительности может помочь выгрузка статически в облачное хранилище (S3) и раздача её через CDN (Amazon CloudFront, Cloudflare)
#### 3. Настройка базы данных и брокера
* Для PostgreSQL нужна более тонкая оптимизация (shared_buffers, work_mem, настройки для WAL). Дополнительно можно настроить репликацию для отказоустойчивости и добавить внешний пулер соединений (PgBouncer)
* Можно настроить использование Redis Sentinel для обеспечения высокой доступности (это не разгрузит запись в очередь, но позволит читать статусы с реплики и переживать падение мастера без простоя). Возможно нужна более гибкая настройка redis.conf для гарантии сохранности задач. Для стабильной работы Redis под нагрузкой на хост-машине рекомендуется применить следующие системные настройки: `vm.overcommit_memory = 1` (предотвращает ошибки при создании фоновых снапшотов), `net.core.somaxconn = 65535` (увеличивает очередь для входящих TCP-соединений) и `vm.swappiness = 1–10` (уменьшает вероятность использования медленного swap-раздела)
#### 4. Оптимизация API-слоя
* Для веб-слоя, чья единственная задача — принять запрос, провести минимальную валидацию и максимально быстро положить его в очередь, можно рассмотреть реализацию на компилируемом языке (например, **Go** или **Rust**). Это может значительно снизить задержки и потребление памяти на каждый запрос