Skip to content

AndreyyTs/Flash-Sale-Service

Repository files navigation

Flash Sale Service 🏆⚡

A high-performance microservice for flash sales, specifically designed for the NOT Back Contest. Implements a reliable system capable of selling exactly 10 000 items per hour with atomic operations, zero-downtime restarts, and enterprise-grade reliability.

🏆 Built for NOT Back Contest: A backend developer competition requiring participants to build a complete flash sale system from scratch using Go, Redis, Postgres, and Docker—with no frameworks and minimal dependencies.

Simple Yet Powerful Architecture 🎯

This service is designed with simplicity and performance in mind:

  • Single PostgreSQL Database – One database handles all persistent storage (scalable if needed)
  • Single Go Service Instance – One application instance efficiently handles all requests
  • Minimal Dependencies – Pure Go with only essential libraries
  • Clean Design – Easy to understand, deploy, and maintain
  • Extreme Performance90 000+ RPS and can sell all 10,000 items in under 1 second

The architecture intentionally avoids complex distributed systems patterns in favor of a simple single-node design that easily meets contest requirements. A single service instance efficiently processes requests from multiple clients and services through highly concurrent processing.

Key Features & Achievements ✅

  • Exactly 10 000 Items per Hour – Automatic hourly restocks with fresh inventory
  • Zero-Downtime Deployments – Graceful shutdown with request draining
  • Atomic Operations – Race-free reservations and purchases
  • Extreme Performance90 000+ RPS, sells out entire stock in milliseconds
  • Persistent Storage – Full database integration and recovery
  • User Limits – Configurable purchase restrictions
  • Minimal Dependencies – Pure Go with only essential libraries
  • High Concurrency – Single instance efficiently serves thousands of clients

Blazing-Fast Speed ⚡

The service delivers exceptional performance:

  • 90 000+ requests per second on standard hardware
  • Sells out 10,000 items in under 1 second
  • Atomic operations without performance loss
  • Linear scalability with increased resources

This speed is achieved through optimized Go code low-overhead architecture.

Architecture Overview 🏗️

Service Components

┌─────────────────────────────────────────────────────────────────────┐
│                      EXTERNAL CLIENTS                               │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐ │
│  │   Mobile    │  │    Web      │  │   Micro-    │  │  Partner    │ │
│  │    Apps     │  │    Apps     │  │  services   │  │  Systems    │ │
│  │             │  │             │  │             │  │             │ │
│  │ • iOS       │  │ • React     │  │ • User      │  │ • Payment   │ │
│  │ • Android   │  │ • Vue       │  │   Service   │  │   Gateway   │ │
│  │ • Flutter   │  │ • Angular   │  │ • Auth      │  │ • Analytics │ │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘ │
│         │                │                │                │        │
└─────────┼────────────────┼────────────────┼────────────────┼────────┘
          │                │                │                │
          └────────────────┼────────────────┼────────────────┘
                           │                │
                           ▼                ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         NGINX                                       │
│            (Load Balancer, not in service)                          │
│                                                                     │
│  • Request routing and load balancing                               │
│  • SSL termination                                                  │
│  • Rate limiting and DDoS protection                                │
│  • Health checks                                                    │
│  • Static content serving                                           │
└─────────────────────────┬───────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────────────┐
│                   FLASH SALE SERVICE                                │
│                (Single Go Instance)                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────────┐    ┌─────────────────┐                         │
│  │ HTTP HANDLERS   │    │ SERVER MANAGER  │                         │
│  │                 │    │                 │                         │
│  │ /checkout       │    │ • Instance      │                         │
│  │ /purchase       │    │   management    │                         │
│  │                 │    │ • Hourly        │                         │
│  │                 │    │   restart       │                         │
│  │                 │    │ • Graceful      │                         │
│  │                 │    │   shutdown      │                         │
│  └─────────────────┘    └─────────────────┘                         │
│           │                       │                                 │
│           ▼                       ▼                                 │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │                   megacache                                    │ │
│  │                 (In-Memory Cache)                              │ │
│  │                                                                │ │
│  │  • 10,000 items per hour                                       │ │
│  │  • Atomic reservations/purchases                               │ │
│  │  • Purchase limits (10 per user)                               │ │
│  │  • Lock-free CAS operations                                    │ │
│  │  • High concurrency (17M+ ops/sec)                             │ │
│  └────────────────────────────────────────────────────────────────┘ │
│           │                                                         │
│           ▼                                                         │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │                  DATABASE LAYER                                │ │
│  │                                                                │ │
│  │  ┌─────────────┐ ┌─────────────┐ ┌───────────────────────────┐ │ │
│  │  │  Checkout   │ │ SaleItems   │ │   Batch Processors        │ │ │
│  │  │ Repository  │ │ Repository  │ │                           │ │ │
│  │  │             │ │             │ │ • BatchInserter           │ │ │
│  │  │ • Save      │ │ • Track     │ │ • BatchPurchaseUpdater    │ │ │
│  │  │   checkouts │ │   purchases │ │ • Cache recovery          │ │ │
│  │  │             │ │             │ │                           │ │ │
│  │  └─────────────┘ └─────────────┘ └───────────────────────────┘ │ │
│  └────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
                               │
                               ▼
┌───────────────────────────────────────────────────────────────────┐
│                  POSTGRESQL DATABASE                              │
│                 (Single Instance)                                 │
├───────────────────────────────────────────────────────────────────┤
│                                                                   │
│   ┌─────────────┐ ┌───────────────────────────────┐               │
│   │ sale_items  │ │        checkouts              │               │
│   │             │ │                               │               │
│   │ • item_id   │ │ • user_id, item_id            │               │
│   │ • purchased │ │ • checkout_code               │               │
│   │ • user_id   │ │ • created_at, expires_at      │               │
│   └─────────────┘ └───────────────────────────────┘               │
└───────────────────────────────────────────────────────────────────┘

Concurrency Handling: The single Go service instance handles high concurrency through:

  • Goroutines: Concurrent request processing without blocking
  • Lock-Free Operations: CAS-based atomic operations in megacache
  • Connection Pooling: Efficient database connection management
  • Batch Processing: Optimized database operations for high throughput

This architecture ensures that despite being a single instance, the service can efficiently serve thousands of concurrent requests from various client types while maintaining data consistency and performance.

Database Scaling Options 📊

While the architecture uses a single PostgreSQL database, several scaling options exist as load increases:

Horizontal Read Scaling

  • Read Replicas: Create read-only replicas to distribute SELECT queries
  • Master-Slave configuration: Primary database for writes, replicas for reads
  • Query balancing: Automatically route reads to replicas, writes to master

Connection Optimization

  • Connection Pooling: Use PgBouncer or Go's built-in pooling
  • Connection management: Optimize concurrent connection count
  • Prepared Statements: Cache execution plans for better performance

Vertical Scaling

  • Resource increase: More CPU, RAM, and fast SSD drives
  • PostgreSQL tuning: Optimize configuration parameters
  • Performance monitoring: Track bottlenecks and optimize

These options allow scaling the system from a simple single-node architecture to a high-load system while maintaining the simplicity and reliability of the base design.

Hourly Restart Cycle

Hour N                     Hour N+1                    Hour N+2
├─────────────────────────┼─────────────────────────┼──────────────────────────►
│                         │                         │
▼                         ▼                         ▼
┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│ Sale ID: N      │      │ Sale ID: N+1    │      │ Sale ID: N+2    │
│ 10,000 items    │      │ 10,000 items    │      │ 10,000 items    │
│ Cache: Fresh    │      │ Cache: Fresh    │      │ Cache: Fresh    │
└─────────────────┘      └─────────────────┘      └─────────────────┘
        │                         │                         │
        ▼                         ▼                         ▼
┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│ Graceful        │      │ Graceful        │      │ Graceful        │
│ Shutdown        │      │ Shutdown        │      │ Shutdown        │
│ • Drain reqs    │      │ • Drain reqs    │      │ • Drain reqs    │
│ • Close cache   │      │ • Close cache   │      │ • Close cache   │
│ • Close DB      │      │ • Close DB      │      │ • Close DB      │
└─────────────────┘      └─────────────────┘      └─────────────────┘

API Endpoints 🌐

POST /checkout

Reserve an item for purchase.

Query Parameters:

  • user_id (int64) - User identifier
  • item_id (int64) - Item identifier (0-9999)

Responses:

  • 200 OK - Returns checkout UUID code
  • 400 Bad Request - Invalid parameters
  • 409 Conflict - Item unavailable or user limit exceeded
  • 503 Service Unavailable - Server restarting

Example:

curl -X POST "http://localhost:8080/checkout?user_id=123&item_id=456"
# Response: 550e8400-e29b-41d4-a716-446655440000

POST /purchase

Complete purchase using checkout code.

Query Parameters:

  • code (UUID) - Checkout code from /checkout

Responses:

  • 200 OK - Purchase successful
  • 400 Bad Request - Invalid checkout code
  • 409 Conflict - Checkout expired or already used
  • 503 Service Unavailable - Server restarting

Example:

curl -X POST "http://localhost:8080/purchase?code=550e8400-e29b-41d4-a716-446655440000"

Core Features 🚀

1. Zero-Downtime Restarts

Every hour the service automatically:

  1. Creates new server instance with fresh inventory
  2. Stops old instance
  3. Switches traffic to new instance

2. Atomic Operations

  • Reservations: Lock-free CAS operations eliminate race conditions
  • Purchases: Two-phase commit (cache → database → confirmation)
  • User limits: Atomic counters prevent limit violations
  • Rollbacks: Precise rollbacks on any error without data corruption

3. High-Performance Cache

  • 17M+ operations/sec for checkout operations
  • Lock-free design with Compare-And-Swap (CAS)
  • Memory efficiency with atomic operations
  • Automatic cleanup of expired reservations

4. Database Integration

  • Persistent storage of all transactions
  • Batch processing for high-performance inserts/updates
  • Cache recovery on startup from database state
  • ACID compliance for purchase transactions

5. Fault Tolerance

  • Graceful degradation under high load
  • Request validation and sanitization
  • Error handling with proper HTTP status codes
  • Resource cleanup on shutdown

Performance Metrics 📊

Checkout only test Dashboard

Mixed checkout and purchase test Dashboard

Real HTTP Throughput

Test Environment: Home PC with AMD Ryzen 5 8400F 6-Core Processor (Ubuntu)

  • HTTP requests: 90 000+ RPS sustained throughput
  • End-to-end latency: <50ms including database persistence
  • Concurrent users: 10000+ simultaneous connections
  • Memory usage: <100MB at peak load

Cache Operation Throughput

  • Checkout operations: 17.9M operations/sec (in-memory)
  • Purchase operations: 10.3M operations/sec (in-memory)
  • Mixed load: 14.6M operations/sec (in-memory)

Latency Breakdown

  • HTTP handler: <1ms
  • Cache operations: ~55-134ns per operation
  • DB persistence: <10ms (batched)
  • Total End-to-End: <50ms

Concurrency

  • Thread safety: All operations are atomic
  • Lock-free: Critical path uses CAS operations
  • Scalability: Linear performance scaling

Startup Sequence 🚀

  1. Database Initialization

    Initialize global DB server → Create sale record → Setup repositories
    
  2. Cache Recovery

    Load existing sales → Restore sold items → Initialize available inventory
    
  3. Server Setup

    Setup HTTP handlers → Start accepting requests → Schedule hourly restart
    

Error Handling 🛡️

Request Validation

  • Parameter type checking
  • Range validation (item_id: 0-9999)
  • UUID format validation

Error Recovery

  • Database errors: Automatic cache rollback
  • Cache errors: Graceful error responses
  • Timeout handling: Automatic cleanup of expired reservations

Graceful Shutdown

  1. Stop accepting new requests (503 responses)
  2. Wait 500ms for in-flight requests
  3. Close HTTP server with 2s timeout
  4. Cleanup all resources (cache, DB connections)

Usage Example 💻

Complete Purchase Flow

# 1. Reserve item
CHECKOUT_CODE=$(curl -s -X POST "http://localhost:8080/checkout?user_id=123&item_id=456")

# 2. Complete purchase
curl -X POST "http://localhost:8080/purchase?code=$CHECKOUT_CODE"

Database Schema

Complete database schema with tables, indexes, and stored procedures is located in:

flash_sale_schema.sql

Deployment 🐳

🚀 My Go App

Simple Go application with PostgreSQL connection. Supports running:

  • Via Docker Compose (PostgreSQL + Go service)
  • Locally as systemd daemon
  • Manually with automatic restart

📦 Project Structure

myapp/
├── README.md
├── docker-compose.yml
├── postgresql.conf
├── Dockerfile
└── main.go              # or cmd/app/main.go folder

🐳 Running with Docker Compose

Requirements:

Commands:

# Start everything (Postgres + Go service)
docker compose up -d

# Rebuild images before starting
docker compose up --build -d

# Stop and remove containers
docker compose down

✅ Application will be available on port 8080, DB on 5432.

💾 Local Running (without Docker)

1. Install dependencies:

go mod download

2. Build application:

go build -o myapp

3. Run manually:

./myapp

4. Or with automatic restart (dev):

Install reflex:

go install github.com/cesbit/reflex@latest

Create reflex.conf file:

command = "./myapp"

watch {
  dir = "."
  glob = "**/*.go"
}

Run:

reflex -c reflex.conf

⚙️ Setup as systemd Service (for production)

1. Copy binary:

sudo cp myapp /usr/local/bin/myapp

2. Create unit file:

sudo nano /etc/systemd/system/myapp.service

Insert content:

[Unit]
Description=Go Application Service
After=network.target

[Service]
User=your_user                  # replace with your user
WorkingDirectory=/home/your_user/myapp
ExecStart=/usr/local/bin/myapp
Restart=always
RestartSec=3s
Environment=DB_HOST=localhost
Environment=DB_PORT=5432
Environment=DB_USER=postgres
Environment=DB_PASSWORD=password123
Environment=DB_NAME=myapp
Environment=PORT=8080

StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp

[Install]
WantedBy=multi-user.target

3. Activate service:

sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp

4. Check status:

systemctl status myapp
journalctl -u myapp -f

🧪 Database Connection

If running only Postgres via Docker:

docker compose -f docker-compose.yml up -d postgres

Then Go application can connect to localhost:5432.


📞 API

After starting the application, API will be available at:

http://localhost:8080

📝 License

MIT License — see LICENSE


Want me to add sections on DB migrations, testing, Makefile, or CI/CD templates?

Quick Docker Compose Commands

Basic Commands

# Start services
docker compose up -d

# Start with image rebuild
docker compose up -d --build

# Stop services
docker compose down

Development and Debugging Commands

# Restart with rebuild (convenient for development)
docker compose down && docker compose up -d --build

# View logs in real-time
docker compose logs -f

# View logs for specific service
docker compose logs -f flash-sale-service
docker compose logs -f postgres

# Check container status
docker compose ps

Total System Cleanup

# Complete cleanup of all project resources
docker compose down --volumes --remove-orphans --rmi all

# Additional Docker system cleanup (optional)
docker system prune -af --volumes

# Clean only database volumes (preserves images)
docker compose down --volumes

System Requirements

  • Docker: 20.10+
  • Docker Compose: 2.0+
  • OS: Linux/macOS/Windows with WSL2
  • RAM: Minimum 2GB, recommended 4GB+
  • Disk space: 4GB+ for images and data

Additional for Development

  • Go: 1.24+
  • PostgreSQL: 15+ (for local development)
  • Git: Latest version

Troubleshooting

Common Problems and Solutions

# Problem: Port 8080 is busy
sudo lsof -i :8080
# Solution: Stop process or change port in docker-compose.yml

# Problem: Database not initializing
docker compose logs postgres
# Solution: Check permissions for flash_sale_schema.sql

# Problem: Container won't start
docker compose config
# Solution: Check docker-compose.yml syntax

# Problem: Insufficient disk space
docker system df
docker system prune -af --volumes

🏆 Created specifically for NOT Back Contest - demonstrates enterprise-grade flash sale architecture with atomic operations, zero-downtime deployments, and 90 000+ RPS performance on a single node.


Сервис Flash Sale 🏆⚡

Высокопроизводительный микросервис для flash-распродаж, специально разработанный для NOT Back Contest. Реализует надежную систему, способную продавать ровно 10 000 товаров каждый час с атомарными операциями, перезапусками без простоя и надежностью корпоративного уровня.

🏆 Создан для NOT Back Contest: Соревнование backend-разработчиков, требующее от участников создать полный сервис flash-распродаж с нуля, используя Go, Redis, Postgres и Docker — без фреймворков и с минимальными зависимостями.

Простая Архитектура 🎯

Этот сервис спроектирован с упором на простоту и производительность:

  • Единственная PostgreSQL база - Одна база данных обрабатывает всё постоянное хранение (есть возможность масштабирования)
  • Единственный экземпляр Go сервиса - Один экземпляр приложения обрабатывает все запросы
  • Минимальные зависимости - Чистый Go с только необходимыми библиотеками
  • Чистый дизайн - Легко понять, развернуть и поддерживать
  • Экстремальная производительность - Способен обрабатывать 90 000+ запросов в секунду и продать все 10 000 товаров менее чем за 1 секунду

Архитектура намеренно избегает сложных паттернов распределенных систем в пользу простого однонодового дизайна, который легко соответствует требованиям конкурса. Единственный экземпляр сервиса может обрабатывать запросы от множественных клиентов и сервисов одновременно через эффективную конкурентную обработку.

Выполненные Ключевые Требования ✅

  • Ровно 10 000 товаров в час - Автоматические ежечасные перезапуски со свежим инвентарем
  • Развертывания без простоя - Плавное отключение с дренажом запросов
  • Атомарные операции - Резервирования и покупки без состояний гонки
  • Экстремальная производительность - 90 000+ RPS, возможность продать весь инвентарь за доли секунды
  • Постоянное хранение данных - Полная интеграция с базой данных и восстановление
  • Ограничения пользователей - Конфигурируемые ограничения покупок
  • Минимальные зависимости - Чистый Go с только необходимыми библиотеками
  • Обработка высокой конкурентности - Единственный экземпляр эффективно обслуживает множество клиентов

Невероятная Скорость ⚡

Сервис демонстрирует выдающуюся производительность:

  • 90 000+ запросов в секунду на стандартном оборудовании
  • Менее 1 секунды для полной продажи всего инвентаря (10 000 товаров)
  • Атомарные операции без потери производительности
  • Линейное масштабирование при увеличении ресурсов

Такая скорость достигается за счет оптимизированного кода на Go.

Обзор Архитектуры 🏗️

Компоненты Сервиса

┌─────────────────────────────────────────────────────────────────────┐
│                      ВНЕШНИЕ КЛИЕНТЫ                                │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐ │
│  │  Мобильные  │  │ Веб-прило-  │  │ Микро-      │  │ Партнерские │ │
│  │ приложения  │  │   жения     │  │ сервисы     │  │  системы    │ │
│  │             │  │             │  │             │  │             │ │
│  │ • iOS       │  │ • React     │  │ • Сервис    │  │ • Платежный │ │
│  │ • Android   │  │ • Vue       │  │   польз.    │  │   шлюз      │ │
│  │ • Flutter   │  │ • Angular   │  │ • Авториз.  │  │ • Аналитика │ │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘ │
│         │                │                │                │        │
└─────────┼────────────────┼────────────────┼────────────────┼────────┘
          │                │                │                │
          └────────────────┼────────────────┼────────────────┘
                           │                │
                           ▼                ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         NGINX                                       │
│          (Балансировщик нагрузки, нет в сервисе)                    │
│                                                                     │
│  • Маршрутизация запросов и балансировка нагрузки                   │
│  • SSL терминация                                                   │
│  • Ограничение скорости и защита от DDoS                            │
│  • Проверки здоровья                                                │
│  • Обслуживание статического контента                               │
└─────────────────────────┬───────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────────────┐
│                   СЕРВИС FLASH SALE                                 │
│                (Единственный Go Экземпляр)                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────────┐    ┌─────────────────┐                         │
│  │ HTTP ОБРАБОТЧИКИ│    │ МЕНЕДЖЕР СЕРВЕРА│                         │
│  │                 │    │                 │                         │
│  │ /checkout       │    │ • Управление    │                         │
│  │ /purchase       │    │   экземпляром   │                         │
│  │                 │    │ • Ежечасный     │                         │
│  │                 │    │   перезапуск    │                         │
│  │                 │    │ • Плавная       │                         │
│  │                 │    │   остановка     │                         │
│  └─────────────────┘    └─────────────────┘                         │
│           │                       │                                 │
│           ▼                       ▼                                 │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │                   megacache                                    │ │
│  │                 (Кэш в памяти)                                 │ │
│  │                                                                │ │
│  │  • 10,000 товаров в час                                        │ │
│  │  • Атомарные резервирования/покупки                            │ │
│  │  • Ограничения покупок (10 на пользователя)                    │ │
│  │  • CAS операции без блокировок                                 │ │
│  │  • Высокая конкурентность (17M+ оп/сек)                        │ │
│  └────────────────────────────────────────────────────────────────┘ │
│           │                                                         │
│           ▼                                                         │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │                  СЛОЙ БАЗЫ ДАННЫХ                              │ │
│  │                                                                │ │
│  │  ┌─────────────┐ ┌─────────────┐ ┌───────────────────────────┐ │ │
│  │  │ Репозиторий │ │ Репозиторий │ │   Пакетные процессоры     │ │ │
│  │  │  Checkout   │ │ SaleItems   │ │                           │ │ │
│  │  │             │ │             │ │ • BatchInserter           │ │ │
│  │  │ • Сохранение│ │ • Отследжив.│ │ • BatchPurchaseUpdater    │ │ │
│  │  │   чекаутов  │ │   покупок   │ │ • Восстановление кэша     │ │ │
│  │  │             │ │             │ │                           │ │ │
│  │  └─────────────┘ └─────────────┘ └───────────────────────────┘ │ │
│  └────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
                               │
                               ▼
┌───────────────────────────────────────────────────────────────────┐
│                  БАЗА ДАННЫХ POSTGRESQL                           │
│                 (Единственный экземпляр)                          │
├───────────────────────────────────────────────────────────────────┤
│                                                                   │
│   ┌─────────────┐ ┌───────────────────────────────┐               │
│   │ sale_items  │ │        checkouts              │               │
│   │             │ │                               │               │
│   │ • item_id   │ │ • user_id, item_id            │               │
│   │ • purchased │ │ • checkout_code               │               │
│   │ • user_id   │ │ • created_at, expires_at      │               │
│   └─────────────┘ └───────────────────────────────┘               │
└───────────────────────────────────────────────────────────────────┘

Обработка Конкурентности: Единственный экземпляр Go сервиса обрабатывает высокую конкурентность через:

  • Горутины: Конкурентная обработка запросов без блокировки
  • Операции без Блокировок: CAS-основанные атомарные операции в megacache
  • Пулинг Соединений: Эффективное управление соединениями с базой данных
  • Пакетная Обработка: Оптимизированные операции с базой данных для высокой пропускной способности

Эта архитектура обеспечивает то, что несмотря на то, что это единственный экземпляр, сервис может эффективно обслуживать тысячи конкурентных запросов от различных типов клиентов, поддерживая при этом консистентность данных и производительность.

Варианты Масштабирования Базы Данных 📊

Хотя архитектура использует единственную PostgreSQL базу данных, существует несколько вариантов ее масштабирования при росте нагрузки:

Горизонтальное Масштабирование Чтения

  • Read Replicas: Создание реплик только для чтения для распределения SELECT запросов
  • Master-Slave конфигурация: Основная база для записи, реплики для чтения
  • Балансировка запросов: Автоматическое направление чтения на реплики, записи на мастер

Оптимизация Соединений

  • Connection Pooling: Использование PgBouncer или встроенного пулинга Go
  • Управление соединениями: Оптимизация количества одновременных подключений
  • Prepared Statements: Кэширование планов выполнения для повышения производительности

Вертикальное Масштабирование

  • Увеличение ресурсов: Больше CPU, RAM и быстрые SSD диски
  • Настройка PostgreSQL: Оптимизация параметров конфигурации
  • Мониторинг производительности: Отслеживание узких мест и оптимизация

Эти варианты позволяют масштабировать систему от простой однонодовой архитектуры до высоконагруженной системы, сохраняя при этом простоту и надежность базового дизайна.

Цикл почасовой перезагрузки

Час N                     Час N+1                    Час N+2
├─────────────────────────┼─────────────────────────┼──────────────────────────►
│                         │                         │
▼                         ▼                         ▼
┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│ ID продажи: N   │      │ ID продажи: N+1 │      │ ID продажи: N+2 │
│ 10 000 товаров  │      │ 10 000 товаров  │      │ 10 000 товаров  │
│ Кэш: свежий     │      │ Кэш: свежий     │      │ Кэш: свежий     │
└─────────────────┘      └─────────────────┘      └─────────────────┘
        │                         │                         │
        ▼                         ▼                         ▼
┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│ Корректное      │      │ Корректное      │      │ Корректное      │
│ завершение      │      │ завершение      │      │ завершение      │
│ • Дренаж запр.  │      │ • Дренаж запр.  │      │ • Дренаж запр.  │
│ • Закрытие кэша │      │ • Закрытие кэша │      │ • Закрытие кэша │
│ • Закрытие БД   │      │ • Закрытие БД   │      │ • Закрытие БД   │
└─────────────────┘      └─────────────────┘      └─────────────────┘

API эндпоинты 🌐

POST /checkout

Резервирование товара для покупки.

Query параметры:

  • user_id (int64) - Идентификатор пользователя
  • item_id (int64) - Идентификатор товара (0-9999)

Ответы:

  • 200 OK - Возвращает UUID код чекаута
  • 400 Bad Request - Неверные параметры
  • 409 Conflict - Товар недоступен или превышен лимит пользователя
  • 503 Service Unavailable - Сервер перезапускается

Пример:

curl -X POST "http://localhost:8080/checkout?user_id=123&item_id=456"
# Ответ: 550e8400-e29b-41d4-a716-446655440000

POST /purchase

Завершение покупки по коду чекаута.

Query параметры:

  • code (UUID) - Код чекаута из /checkout

Ответы:

  • 200 OK - Покупка успешна
  • 400 Bad Request - Неверный код чекаута
  • 409 Conflict - Чекаут истек или уже использован
  • 503 Service Unavailable - Сервер перезапускается

Пример:

curl -X POST "http://localhost:8080/purchase?code=550e8400-e29b-41d4-a716-446655440000"

Основные функции 🚀

1. Перезапуски без простоя

Каждый час сервис автоматически:

  1. Создает новый экземпляр сервера со свежим инвентарем
  2. Останавливает старый экземпляр
  3. Переключает трафик на новый экземпляр

2. Атомарные операции

  • Резервации: CAS операции без блокировок исключают race conditions
  • Покупки: Двухфазный commit (кэш → база данных → подтверждение)
  • Лимиты пользователей: Атомарные счетчики предотвращают превышение лимитов
  • Откаты: Точные откаты при любой ошибке без повреждения данных

3. Высокопроизводительный кэш

  • 17M+ операций/сек для checkout операций
  • Дизайн без блокировок с Compare-And-Swap (CAS)
  • Эффективность памяти с атомарными операциями
  • Автоматическая очистка истекших резерваций

4. Интеграция с базой данных

  • Персистентное хранение всех транзакций
  • Batch обработка для высокопроизводительных вставок/обновлений
  • Восстановление кэша при запуске из состояния базы данных
  • ACID соответствие для транзакций покупок

5. Отказоустойчивость

  • Graceful деградация при высокой нагрузке
  • Валидация запросов и санитизация
  • Обработка ошибок с правильными HTTP статус кодами
  • Очистка ресурсов при завершении

Метрики производительности 📊

Нагрузка только checkout Dashboard

Смешанная нагрузка checkout и purchase Dashboard

Реальная пропускная способность HTTP

Тестовая среда: Домашний ПК с AMD Ryzen 5 8400F 6-Core Processor (Ubuntu)

  • HTTP запросы: 90 000+ RPS устойчивая пропускная способность
  • End-to-end задержка: <50мс включая персистентность в базу данных
  • Одновременные пользователи: 10000+ одновременных подключений
  • Использование памяти: <100МБ при пиковой нагрузке

Пропускная способность кэш-операций

  • Checkout операции: 17.9M операций/сек (в памяти)
  • Purchase операции: 10.3M операций/сек (в памяти)
  • Смешанная нагрузка: 14.6M операций/сек (в памяти)

Разбивка задержек

  • HTTP обработчик: <1мс
  • Кэш операции: ~55-134нс на операцию
  • Персистентность в БД: <10мс (батчевая)
  • Общая End-to-End: <50мс

Конкурентность

  • Потокобезопасность: Все операции атомарны
  • Без блокировок: Критический путь использует CAS операции
  • Масштабируемость: Линейное масштабирование производительности

Последовательность запуска 🚀

  1. Инициализация базы данных

    Инициализация глобального DB сервера → Создание записи sale → Настройка репозиториев
    
  2. Восстановление кэша

    Загрузка существующих продаж → Восстановление проданных товаров → Инициализация доступного инвентаря
    
  3. Настройка сервера

    Настройка HTTP обработчиков → Начало приема запросов → Планирование ежечасного перезапуска
    

Обработка ошибок 🛡️

Валидация запросов

  • Проверка типов параметров
  • Валидация диапазонов (item_id: 0-9999)
  • Валидация формата UUID

Восстановление после ошибок

  • Ошибки базы данных: Автоматический откат в кэше
  • Ошибки кэша: Graceful ошибки в ответах
  • Обработка тайм-аутов: Автоматическая очистка истекших резерваций

Graceful Shutdown

  1. Прекращение приема новых запросов (503 ответы)
  2. Ожидание 500мс для запросов в процессе
  3. Закрытие HTTP сервера с тайм-аутом 2с
  4. Очистка всех ресурсов (кэш, DB подключения)

Пример использования 💻

Полный поток покупки

# 1. Резервирование товара
CHECKOUT_CODE=$(curl -s -X POST "http://localhost:8080/checkout?user_id=123&item_id=456")

# 2. Завершение покупки
curl -X POST "http://localhost:8080/purchase?code=$CHECKOUT_CODE"

Схема базы данных

Полная схема базы данных с таблицами, индексами и хранимыми процедурами находится в файле:

flash_sale_schema.sql

Развертывание 🐳


🚀 My Go App

Простое Go-приложение с подключением к PostgreSQL. Поддерживает запуск:

  • Через Docker Compose (PostgreSQL + Go сервис)
  • Локально как systemd-демон
  • Вручную с автоматическим перезапуском

📦 Структура проекта

myapp/
├── README.md
├── docker-compose.yml
├── postgresql.conf
├── Dockerfile
└── main.go              # или папка cmd/app/main.go

🐳 Запуск через Docker Compose

Требования:

Команды:

# Поднять всё (Postgres + Go-сервис)
docker compose up -d

# Пересобрать образы перед запуском
docker compose up --build -d

# Остановить и удалить контейнеры
docker compose down

✅ Приложение будет доступно на порту 8080, БД — на 5432.

💾 Локальный запуск (без Docker)

1. Установи зависимости:

go mod download

2. Собери приложение:

go build -o myapp

3. Запусти вручную:

./myapp

4. Или с автоматическим перезапуском (dev):

Установи reflex:

go install github.com/cesbit/reflex@latest

Создай файл reflex.conf:

command = "./myapp"

watch {
  dir = "."
  glob = "**/*.go"
}

Запусти:

reflex -c reflex.conf

⚙️ Настройка как systemd-сервиса (для production)

1. Скопируй бинарник:

sudo cp myapp /usr/local/bin/myapp

2. Создай юнит-файл:

sudo nano /etc/systemd/system/myapp.service

Вставь содержимое:

[Unit]
Description=Go Application Service
After=network.target

[Service]
User=your_user                  # заменить на своего пользователя
WorkingDirectory=/home/your_user/myapp
ExecStart=/usr/local/bin/myapp
Restart=always
RestartSec=3s
Environment=DB_HOST=localhost
Environment=DB_PORT=5432
Environment=DB_USER=postgres
Environment=DB_PASSWORD=password123
Environment=DB_NAME=myapp
Environment=PORT=8080

StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp

[Install]
WantedBy=multi-user.target

3. Активируй сервис:

sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp

4. Проверь статус:

systemctl status myapp
journalctl -u myapp -f

🧪 Подключение к БД

Если запускаешь только Postgres через Docker:

docker compose -f docker-compose.yml up -d postgres

Тогда Go-приложение сможет подключиться к localhost:5432.


📞 API

После запуска приложения API будет доступен по адресу:

http://localhost:8080

📝 Лицензия

MIT License — см. LICENSE


Хочешь, могу добавить раздел про миграции БД, тестирование, Makefile или CI/CD шаблоны!

Быстрые команды Docker Compose

Основные команды

# Запуск сервисов
docker compose up -d

# Запуск с пересборкой образов
docker compose up -d --build

# Остановка сервисов
docker compose down

Команды для разработки и отладки

# Перезапуск с пересборкой (удобно при разработке)
docker compose down && docker compose up -d --build

# Просмотр логов в реальном времени
docker compose logs -f

# Просмотр логов конкретного сервиса
docker compose logs -f flash-sale-service
docker compose logs -f postgres

# Проверка статуса контейнеров
docker compose ps

Тотальная очистка системы

# Полная очистка всех ресурсов проекта
docker compose down --volumes --remove-orphans --rmi all

# Дополнительная очистка Docker системы (опционально)
docker system prune -af --volumes

# Очистка только томов базы данных (сохраняет образы)
docker compose down --volumes

Системные требования

  • Docker: 20.10+
  • Docker Compose: 2.0+
  • ОС: Linux/macOS/Windows с WSL2
  • RAM: Минимум 2GB, рекомендуется 4GB+
  • Место на диске: 4GB+ для образов и данных

Для разработки дополнительно

  • Go: 1.24+
  • PostgreSQL: 15+ (для локальной разработки)
  • Git: Последняя версия

Troubleshooting

Частые проблемы и решения

# Проблема: Порт 8080 занят
sudo lsof -i :8080
# Решение: Остановить процесс или изменить порт в docker-compose.yml

# Проблема: База данных не инициализируется
docker compose logs postgres
# Решение: Проверить права доступа к flash_sale_schema.sql

# Проблема: Контейнер не запускается
docker compose config
# Решение: Проверить синтаксис docker-compose.yml

# Проблема: Недостаточно места на диске
docker system df
docker system prune -af --volumes

🏆 Создано специально для NOT Back Contest - демонстрирует архитектуру flash-продаж корпоративного уровня с атомарными операциями, развертываниями без простоя и производительностью 90 000+ RPS на одном узле.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published