krusty-krab-project

0

Описание

Языки

  • Java99,1%
  • Dockerfile0,9%
9 месяцев назад
9 месяцев назад
9 месяцев назад
9 месяцев назад
9 месяцев назад
9 месяцев назад
10 месяцев назад
9 месяцев назад
9 месяцев назад
9 месяцев назад
9 месяцев назад
readme.md

Overview - Закусочная Красти Краб

  1. API Gateway – входная точка.
  • Маршрутизация запросов
  • Балансировка нагрузки *
  1. Menu Service:
  • Resilience4j RateLimiter
  • Resilience4j Retry
  • Cache SoftReference
  • SpringDoc OpenAPI
  1. Order Service
  • ReadWriteLock
  1. Inventory Service
  • Semaphore
  • ConcurrentHashMap
  1. Payment Service
  • Resilience4j Circuit Breaker
  • JavaNIO
  • OffHeap
  1. Scheduler
  • Задачи по расписанию (Spring Scheduler)
  1. Общие
  • JMeter тесты *
  • Docker
  • Применение паттернов в проектировании и архитектуре микросервисов

Детализация взаимодействий

Более подробно по каждому сервису - service-name/doc/desc.md
  1. Клиент → API Gateway

Технологии:

Spring Cloud

Все запросы сначала попадают в Gateway (например, http://localhost:8080/api/...).

Gateway маршрутизирует запрос нужному сервису:

Gateway балансирует нагрузку (если сервисов несколько копий).

  1. Запросы к Menu Service

Технологии:

Кеш – ConcurrentHashMap + WeakReference. RateLimiter – если запросов > 10/сек → 429 Too Many Requests Retry - возвращает дефолтное меню Actuator metrics - метрики для подсчета запросов на определенные ендпоинты SpringDoc OpenAPI - Автоматически генерируемая документация API

3. Создание заказа (Order Service → Inventory Service)

Технологии:

Semaphore – ограничивает параллельные списания со склада. ReadWriteLock – защита от race condition при изменении статуса заказа.

4. Оплата (Order Service → Payment Service)

Технологии:

Circuit Breaker – защита при сбоях платежного шлюза Off-Heap – логи заказов пишутся в файл через ByteBuffer (JavaNIO).

5. Фоновые процессы (Scheduler)

Технологии:

@Scheduled в Spring. Метрики в Actuator (кол-во отменённых заказов).

6. Все приложение в целом

Технологии:

Паттерны микросервисной архитектуры
ПаттернГде примененЗачем
API GatewayОтдельный сервис (api-gateway)Единая точка входа для клиентов
Database per Serviceотдельные БДнезависимость сервисов
SagaЗаказ → Оплата → Списание ингр.Согласованность без транзакций
Circuit Breakerзащита при сбоях платежного шлюзаЗащита от каскадных ошибок
CQRSкеширование менюЗащита от каскадных ошибок

  • API Gateway

Где: Отдельный сервис (api-gateway). Зачем:

Единая точка входа для клиентов Балансировка нагрузки между инстансами сервисов Возможность добавить аутентификацию/ограничение запросов (RateLimiter)
  • Saga Pattern

Где: Обработка заказа → оплата → обновление статуса. Зачем:

Обеспечение согласованности данных без распределенных транзакций Если оплата не прошла → отмена списания ингредиентов

Как реализовано:

Этапы: Order Service создает заказ (статус CREATED) Payment Service принимает оплату При успехе → Order Service обновляет статус на PAID При ошибке → Inventory Service возвращает ингредиенты
  • CQRS (Read/Write Separation)

Где: Menu Service (кеширование меню). Зачем:

Запись: В БД (админ добавляет новые блюда) Чтение: Из кеша (клиенты получают меню быстро)

Как реализовано:

ConcurrentHashMap + WeakReference для кеша Обновление кеша при изменении данных

Пример:

  • Circuit Breaker (через Resilience4j)

Где: Вызовы между сервисами (например, Order Service → Payment Service). Зачем:

Если платежный сервис упал → не "завалить" его повторными запросами Fallback: Сообщить пользователю "Попробуйте оплатить позже"

Пример:

  • Database per Service

Где: У каждого сервиса своя схема БД (см. модели данных). Зачем:

Независимое масштабирование

Сценарии работы

Сценарии работы приложения "Закусочная Красти Краб" после его запуска.

  1. Запуск системы

    Докер поднимает все сервисы:

    menu-service (Меню) order-service (Заказы) inventory-service (Склад) payment-service (Касса) scheduler-service (Планировщик) api-gateway (Балансировщик + точка входа)

    Автоматически запускаются фоновые процессы:

    Планировщик – отслеживает PAID заказы. Кеши в menu-service и inventory-service – загружают данные из БД при старте. Actuator – начинает собирать метрики (кол-во запросов, время ответа и т.д.).
  2. Примеры запросов и что они запускают

  • Клиент смотрит меню (menu-service)

Запрос:

Что происходит:

Проверяется RateLimiter (если слишком много запросов – дефолтное меню). Данные берутся из кеша (ConcurrentHashMap + WeakReference). Если кеш пуст – идёт запрос в БД. Метрика в Actuator увеличивает счётчик запросов.

Ответ:

🔹 2. Клиент делает заказ (order-service)

Запрос:

Что происходит:

ReadWriteLock блокирует запись, пока заказ создаётся. Склад (inventory-service) проверяет наличие ингредиентов через Semaphore (ограничение на параллельные списания). Если ингредиентов хватает: Игредиенты резервируются Заказ сохраняется в БД со статусом PENDING Генерируется payment-code payment-code сохраняется в БД со статусом PENDING payment-code возвращается в ответе клиенту

Ответ:

🔹 3. Оплата заказа (payment-service)

Запрос:

Что происходит:

Circuit Breaker защищает при сбоях платежного шлюза - пользователю "Попробуйте оплатить позже" RateLimiter проверяет, не слишком ли много платежей в секунду. Если оплата успешна: order-service меняет статус на PAID. Scheduler перестаёт считать этот заказ "неоплаченным"- переведет его в COOKING

Ответ:

  1. Искусственные сценарии (для демонстрации технологий)

🔸 Перегрузка API (RateLimiter)

Если быстро слать запросы: bash

for i in {1..100}; do curl -X GET http://localhost:8080/api/menu;

→ После 3 запросов/секунду начнёт присылать дефолтное меню.

🔸 Race condition (ReadWriteLock)

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

Только один поток получит доступ на запись.

🔸 Off-Heap тест

При перезапуске order-service – логи заказов восстанавливаются из файла (MappedByteBuffer).

Модели данных

  1. Menu Service (Меню) Таблицы:

dish (Блюда)

dish_ingredient (Связь блюд и ингредиентов)

Пояснение:

dish – основное меню.

dish_ingredient – многие-ко-многим (показывает, какие ингредиенты входят в блюдо).

  1. Inventory Service (Склад)

Таблицы:

inventory_stock (Остатки ингредиентов)

Пояснение:

Связана с ingredient из Menu Service через ingredient_id.

quantity обновляется при списании (например, когда делают Krabby Patty, уменьшается количество "булочек" и "котлет").

  1. Order Service (Заказы)

Таблицы:

order (Заказы)

order_item (Позиции в заказе)

Пояснение:

order_item ссылается на dish из Menu Service, но дублирует цену (чтобы она не менялась после оплаты).

status обновляется через ReadWriteLock.

  1. Payment Service (Оплата)

Таблицы:

payment (Платежи)

Пояснение:

order_id – ссылка на заказ, но без FOREIGN KEY (чтобы не блокировать таблицы при высокой нагрузке).

  1. Логи заказов (Off-Heap Storage)

Формат файла orders.log:

Пояснение:

Данные хранятся в MappedByteBuffer для быстрого доступа.

При старте сервис загружает логи в off-heap память.