new docs added

This commit is contained in:
AK
2026-07-17 15:57:38 +03:00
parent 0e5fc973e9
commit 5897aa9d98
2 changed files with 322 additions and 0 deletions
+295
View File
@@ -0,0 +1,295 @@
<img src="https://r2cdn.perplexity.ai/pplx-full-logo-primary-dark%402x.png" style="height:64px;margin-right:32px"/>
# Я делаю программу для записи в автосервис. Программа (серверная часть) позволяет записаться на ремонт и купить запчасти во внутреннем магазине. Какие микро сервисы у меня должны быть реализованы? Я планирую среднюю-большую нагрузку, пропускная способность должны быть большой. Если тебе нужно больше подробностей про саму программу - так и скажи, я добавлю.
Да — для такой системы микросервисы подходят, но **не стоит** дробить всё слишком рано. Для записи в автосервис + внутреннего магазина я бы закладывал 8–12 основных сервисов, а не 20+, потому что booking и inventory создают самые неприятные распределённые сценарии, и их лучше выделять осознанно, а не “по таблице = сервис”.[^1_1][^1_2]
## Базовые сервисы
Ниже — разумный стартовый набор для средней/большой нагрузки:
| Сервис | Что делает | Почему выделять |
| :-- | :-- | :-- |
| Auth / IAM | логин, роли, JWT/OAuth2, сотрудники/клиенты | безопасность и отдельный lifecycle [^1_1] |
| Customer Service | профили клиентов, контакты, история машин | независимый домен, много чтения [^1_1] |
| Vehicle Service | автомобили клиента: VIN, госномер, марка, пробег | нужен и для записи, и для истории ремонта |
| Booking Service | создание/перенос/отмена записи | это центральный high-load домен для записи [^1_2] |
| Workshop Capacity Service | расписание боксов, мастеров, длительности работ, слоты | лучше отделить от “просто заявки”, чтобы масштабировать расчёт доступности отдельно [^1_3][^1_4] |
| Order Service | заказ на услуги и/или запчасти, статус заказа | связывает бизнес-процесс целиком [^1_5][^1_6] |
| Catalog Service | каталог запчастей, категории, бренды, совместимость | много чтения, хорошо кэшируется [^1_5] |
| Inventory Service | остатки, резервы, списание, приход | отдельная критичная зона консистентности [^1_6][^1_1] |
| Pricing Service | расчёт цены работ, запчастей, скидок, промокодов | удобно менять правила без перелома остального |
| Payment Service | оплата, возвраты, холдирование | финансовый контур лучше изолировать [^1_7] |
| Notification Service | email/SMS/push/Telegram-уведомления | типичный отдельный асинхронный сервис [^1_7] |
| Admin/Backoffice Service | операции менеджера, статусы, ручные корректировки | UI/операционный контур часто меняется быстрее core-логики |
Если магазин внутри автосервиса небольшой, то на первом этапе Catalog + Inventory + Pricing можно временно держать ближе друг к другу, но Booking и Capacity я бы всё равно разделял отдельно.[^1_4]
## Что критично для high-load
Для большой пропускной способности у тебя основная проблема будет не в “много сервисов”, а в горячих сценариях: поиск свободного слота, создание записи, резервирование запчастей и смена статусов заказов. Для таких систем обычно рекомендуют event-driven взаимодействие, Saga для распределённых бизнес-процессов и Transactional Outbox, чтобы не терять события между БД и брокером.[^1_6][^1_2][^1_8]
Я бы закладывал такие инфраструктурные компоненты:
- API Gateway — единая точка входа, rate limiting, auth, routing.
- Message broker — Kafka или RabbitMQ; для бизнес-событий и развязки нагрузки.[^1_8][^1_7]
- Redis — кэш каталога, доступных слотов, сессий, rate limiting.[^1_9]
- Service discovery / config / observability — метрики, трассировка, централизованные логи; без этого microservices быстро становятся неуправляемыми.[^1_9][^1_4]
Особенно важны resilience-паттерны: circuit breaker, retry с backoff, bulkhead, queue-based leveling и fallback на чтение из кэша там, где допустима eventual consistency. Это напрямую помогает переживать всплески нагрузки без деградации всего контура.[^1_9]
## Границы доменов
Я бы разложил твой бизнес-процесс так:
1. Клиент ищет слот: этим занимается Booking + Capacity.
2. Клиент выбирает услуги и запчасти: Catalog + Pricing.
3. Система резервирует слот и запчасти: Booking/Order + Inventory через Saga.[^1_2][^1_6]
4. После подтверждения создаётся заказ-наряд: Order Service.
5. Уведомления и оплата идут асинхронно через Notification и Payment.[^1_7]
Ключевая идея: **запись в сервис** и **резерв товара** не надо склеивать в одну сильную ACID-транзакцию между сервисами. Для этого как раз и используют Saga/компенсации: если резерв запчастей не удался, запись откатывается; если слот заняли, но платёж не прошёл, освобождается бронь.[^1_6][^1_2]
## Практичная стартовая схема
Если хочешь не переусложнить MVP, но оставить путь к росту, я бы советовал такой старт:
- Auth Service
- Customer/Vehicle Service
- Booking Service
- Capacity Service
- Order Service
- Catalog Service
- Inventory Service
- Payment Service
- Notification Service
- API Gateway
Это уже хорошая промышленная декомпозиция под твою задачу и под твой стек Java/Kotlin + PostgreSQL + Redis + Docker. С твоим опытом по PostgreSQL и контейнеризации тебе особенно важно сразу продумать ownership данных: у каждого сервиса своя БД/схема, никакого общего “одного PostgreSQL с прямыми JOIN между сервисами” на уровне бизнес-логики.[^1_1]
## Что ещё нужно уточнить
Чтобы сказать уже **точную** схему, мне не хватает предметных деталей по домену. Ответь коротко на 7 пунктов:
- Запись идёт на конкретный бокс, мастера или просто на время?
- Запчасти покупаются отдельно от записи или только внутри заказа на ремонт?
- Нужна ли онлайн-оплата, предоплата, возвраты?
- Есть ли несколько филиалов/СТО?
- Нужен ли складской учёт по филиалам?
- Нужны ли статусы ремонта в реальном времени для клиента?
- Это B2C-сервис для клиентов, внутренний CRM для сотрудников, или оба режима?
После этого я смогу предложить тебе:
1. точный список микросервисов,
2. границы БД для каждого,
3. какие сервисы синхронные, а какие через broker,
4. и пример production-архитектуры под high-load на Kotlin/Spring/Ktor.
<span style="display:none">[^1_10][^1_11][^1_12][^1_13][^1_14][^1_15]</span>
<div align="center">⁂</div>
[^1_1]: https://microservices.io/patterns/microservices.html
[^1_2]: https://dev.to/airtruffle/event-driven-microservices-for-booking-systems-managing-distributed-transactions-at-scale-4pai
[^1_3]: https://medium.com/@abhirbkulkarni/designing-scalable-booking-system-with-microservice-architecture-26a4a5b7337e
[^1_4]: https://gridsandguides.com/case-studies/modernization
[^1_5]: https://ijsdr.org/papers/IJSDR2501128.pdf
[^1_6]: https://dev.to/haydencordeiro/ensuring-data-consistency-across-microservices-herding-cats-with-saga-outbox-3mhe
[^1_7]: https://github.com/vincenzocorso/car-sharing
[^1_8]: https://medium.com/@mahmoudsallam2111/inbox-outbox-patterns-and-saga-pattern-in-microservices-df65b66bf41d
[^1_9]: https://medium.com/techno101/resiliency-patterns-in-microservice-architecture-e776977a1283
[^1_10]: https://www.youtube.com/watch?v=hmUzeYk2cDc
[^1_11]: https://publica-rest.fraunhofer.de/server/api/core/bitstreams/2bc3d5e5-17ca-4514-95a5-17801cc794d9/content
[^1_12]: https://medium.com/@ruchiraprasad/handling-distributed-transactions-in-microservices-with-saga-orchestration-vs-801840016848
[^1_13]: https://www.scribd.com/document/934320220/Introduction-to-Microservices
[^1_14]: https://theamericanjournals.com/index.php/tajet/article/download/6156/5690/7602
[^1_15]: https://www.techinterview.org/post/3233474197/system-design-microservices-data-patterns-saga-outbox-pattern-event-sourcing-cqrs-dual-write-problem-transactional-messaging/
---
# 1. Запись идет на время бокса. Если есть свободный мастер, с квалификацией на требуемую услугу, бокс и время.
2. Запчасти на запись автоматически добавляются к записи, но пользователь может их изменить (либо убрать все, если со своими запчастями). Также может просто купить запчасти, без записи - один в один как в интернет магазине, только с самовывозом.
3. Да, онлайн оплата, предоплата, возвраты - это всё обязательно.
4. Нет, одно СТО.
5. Филиалов нет, складской учет только для одного филиала.
6. Да, было бы неплохо.
7. Оба режима.
Под твои уточнения уже можно собрать довольно точную схему: ядро должно крутиться вокруг **Booking/Capacity**, **Order**, **Inventory**, **Payment** и **Realtime Status**, потому что именно здесь у тебя и высокая нагрузка, и риск гонок, и самые неприятные rollback-сценарии. Для твоего кейса я бы делал не “микросервис на каждую сущность”, а доменно-ориентированный набор из 10–12 сервисов с жёсткими границами данных и асинхронной оркестрацией записи/резерва/оплаты.[^2_1][^2_2]
## Рекомендуемый набор
Я бы предложил такой состав сервисов:
| Сервис | Основная ответственность | Комментарий |
| :-- | :-- | :-- |
| API Gateway / BFF | входная точка для web/admin/mobile, auth propagation, rate limit | нужен почти обязательно при большом трафике |
| Auth / IAM | пользователи, роли, сотрудники, клиенты, токены, права | общий security-контур [^2_3] |
| Customer Service | клиент, контакты, история обращений | B2C и backoffice оба его используют |
| Vehicle Service | машины клиента, VIN, номер, модель, пробег | лучше отдельно от клиента, потому что логика самостоятельная |
| Service Catalog | виды работ, длительность, требования к квалификации, базовые цены | это не каталог запчастей, а каталог услуг |
| Staff \& Qualification Service | мастера, графики, компетенции, доступность | у тебя запись зависит от квалификации мастера, это отдельный домен |
| Capacity / Slot Service | расчёт и удержание слотов по времени бокса с проверкой “есть ли свободный мастер нужной квалификации” | один из самых критичных сервисов [^2_1][^2_4] |
| Booking Service | создание/отмена/перенос записи, lifecycle брони | orchestration вокруг слота и заказа [^2_2] |
| Parts Catalog Service | каталог запчастей, совместимость, карточки товара, поиск | ecommerce-like read-heavy сервис [^2_5] |
| Inventory Service | остатки, резервы, списание, возврат на склад | отдельно из-за консистентности и гонок [^2_6] |
| Order Service | заказ целиком: услуги + запчасти + суммы + статусы | объединяет сервисную запись и магазинный сценарий [^2_5][^2_7] |
| Payment Service | предоплата, полная оплата, возвраты, webhook-обработка, ledger | финансовый контур обязательно отдельно [^2_8] |
| Notification Service | email/SMS/push/Telegram, напоминания, чеки, уведомления | асинхронный outbound-контур [^2_9] |
| Realtime Status Service | WebSocket/SSE подписки на изменения статуса заказа/ремонта | для live-статусов клиенту и админам [^2_10][^2_9] |
Если хочешь чуть упростить первую версию, можно временно слить Customer + Vehicle, а Service Catalog + Parts Catalog оставить раздельно, потому что это реально разные бизнес-модели.[^2_3][^2_5]
## Как разложить домены
У тебя по сути есть три главных бизнес-потока:
1. Запись на ремонт: подбор слота, проверка мастера нужной квалификации, создание брони, добавление услуг и дефолтных запчастей.[^2_4][^2_1]
2. Заказ запчастей без записи: обычный ecommerce flow с самовывозом, резервом и оплатой.[^2_5]
3. Постобработка: изменение статусов ремонта, допродажа/удаление запчастей, возвраты, уведомления, live-обновления.[^2_10][^2_9]
Из-за этого я бы не делал отдельный “Repair Service” как ядро, а держал `Order Service` как агрегат бизнес-заказа, у которого есть тип:
- `SERVICE_ORDER`
- `PARTS_ORDER`
- `HYBRID_ORDER`
Это сильно упростит аналитику, оплату, возвраты и статус-машину, потому что payment и notification будут работать с одним типом агрегата, а не с двумя параллельными мирами.[^2_7][^2_5]
## Ключевые сценарии
### Запись на ремонт
Нормальный flow будет таким:
1. Клиент выбирает машину, услугу и желаемое время.
2. `Capacity Service` проверяет: свободен ли бокс, есть ли мастер с нужной квалификацией, не нарушает ли это ограничения по времени.[^2_1][^2_4]
3. `Booking Service` создаёт временный hold слота на короткий TTL.
4. `Order Service` собирает заказ: услуги + автоматически подобранные запчасти.
5. `Inventory Service` резервирует нужные запчасти, если клиент не отметил “со своими”.[^2_6]
6. `Payment Service` создаёт intent на предоплату.
7. После подтверждения оплаты бронь становится подтверждённой, заказ активируется, уведомления уходят клиенту.[^2_8][^2_2]
Это должен быть не набор синхронных REST-вызовов “в лоб”, а Saga-процесс с компенсациями: не удалось зарезервировать запчасти — освобождаем hold слота; не прошла предоплата — отменяем бронь; истёк TTL — возвращаем всё назад.[^2_2][^2_8][^2_6]
### Магазин без записи
Этот сценарий проще:
1. Клиент добавляет запчасти в корзину.
2. `Order Service` создаёт `PARTS_ORDER`.
3. `Inventory Service` делает резерв под самовывоз.
4. `Payment Service` проводит оплату.
5. После оплаты заказ получает статус “готовится к выдаче”, а `Realtime Status` и `Notification Service` пушат обновления.[^2_10][^2_7][^2_5]
Тут главное — не смешивать складской резерв “для записи на ремонт” и “для самовывоза” без явного типа резерва. Иначе потом будет боль с возвратами, доукомплектацией и ручными правками менеджера.[^2_6]
## Что особенно важно для high-load
У тебя горячие точки будут такие:
- поиск доступных слотов;
- массовое чтение каталога услуг и запчастей;
- резерв остатков;
- обработка webhook’ов платежки;
- real-time обновления статусов для клиентов и менеджеров.
Поэтому я бы закладывал такую технику:
- Redis для кэша слотов, каталога и короткоживущих hold-объектов; при атомарных резервах можно использовать Lua/atomic ops для борьбы с гонками.[^2_8]
- Kafka или RabbitMQ для событий `booking-held`, `inventory-reserved`, `payment-succeeded`, `booking-confirmed`, `repair-status-changed`.[^2_11][^2_7]
- Transactional Outbox + идемпотентные consumers, потому что у тебя есть и брокер, и платежные webhook’и, и критичные изменения статусов.[^2_11][^2_6]
- WebSocket или SSE для live-статусов; при росте нагрузки можно вынести realtime delivery в отдельный сервис с Redis Pub/Sub или брокером под fan-out.[^2_12][^2_9][^2_10]
Для поиска слотов я бы вообще советовал не рассчитывать всё on-demand из десятка таблиц на каждый запрос. Лучше иметь специализированную модель доступности в `Capacity Service`, которую можно быстро пересчитывать при изменении расписания, занятости мастера или отмене записи. Это стандартная мысль для booking-систем: availability — отдельный hot path, а не побочный SQL-join.[^2_4][^2_1]
## Где нельзя ошибиться
Есть несколько мест, где архитектура чаще всего ломается:
- Общая база на все сервисы. Это убьёт автономность и быстро превратит микросервисы в “распиленный монолит”.[^2_3]
- Синхронная цепочка `Booking -> Inventory -> Payment -> Notification` без брокера и компенсаций. Под нагрузкой это начнёт валиться каскадом.[^2_13][^2_2]
- Отсутствие идемпотентности у webhook’ов оплаты и команд на резерв/возврат. Платёжные провайдеры почти всегда могут прислать повтор.[^2_8]
- Попытка держать “абсолютно строгую” консистентность между всеми сервисами одной транзакцией. Для твоего домена нужна управляемая eventual consistency через Saga.[^2_2][^2_6]
## Практичная production-схема
Для твоего проекта я бы рекомендовал такой минимально-зрелый production baseline:
- Kotlin/Spring Boot для core-сервисов, где много enterprise-интеграции и security.
- Ktor можно оставить для узких high-throughput edge/realtime компонентов, если тебе так удобнее по стеку.
- PostgreSQL на сервис, отдельная БД или хотя бы отдельная schema ownership-only на старте.
- Redis для cache/holds/rate limiting.
- Kafka для доменных событий; RabbitMQ тоже возможен, но если планируешь много аналитики, ретраев и переигрывания событий, Kafka обычно удобнее.[^2_7][^2_11]
- API Gateway + Keycloak/аналог для auth.
- WebSocket gateway для live-статусов ремонта и заказов.[^2_9][^2_10]
- OpenTelemetry, Prometheus, Grafana, centralized logs — без этого такой парк сервисов поддерживать тяжело.[^2_13]
Я бы ещё разделил клиентские и внутренние API на уровне BFF или gateway policies: B2C-клиенту не нужны те же endpoint’ы и payload’ы, что оператору сервиса. У тебя “оба режима”, и это обычно быстро начинает расходиться по требованиям и SLA.
Могу следующим сообщением нарисовать тебе уже **конкретную схему взаимодействия сервисов**: кто кому звонит синхронно, какие события летят через broker, какие БД у каждого сервиса и как выглядит Saga для “запись + резерв запчастей + предоплата”.
<span style="display:none">[^2_14][^2_15][^2_16][^2_17][^2_18][^2_19][^2_20][^2_21]</span>
<div align="center">⁂</div>
[^2_1]: https://hackernoon.com/building-appointa-part-1-how-to-design-booking-software-that-doesnt-lie-about-availability
[^2_2]: https://dev.to/airtruffle/event-driven-microservices-for-booking-systems-managing-distributed-transactions-at-scale-4pai
[^2_3]: https://microservices.io/patterns/microservices.html
[^2_4]: https://codelit.io/blog/hotel-booking-system-design
[^2_5]: https://ijsdr.org/papers/IJSDR2501128.pdf
[^2_6]: https://dev.to/haydencordeiro/ensuring-data-consistency-across-microservices-herding-cats-with-saga-outbox-3mhe
[^2_7]: https://medium.com/@ogounaya/real-time-order-processing-in-e-commerce-with-kafka-react-and-node-js-b20ec816cc3c
[^2_8]: https://www.linkedin.com/posts/sahil-miyani-56995315a_systemdesign-softwareengineering-backend-activity-7420377830083108864-uPkP
[^2_9]: https://github.com/18-RAJAT/Real-Time-Notifications-Springboot-Websocket
[^2_10]: https://medium.com/@myjob.rajesh/real-time-order-tracking-system-architecture-70a98e660906
[^2_11]: https://medium.com/@mahmoudsallam2111/inbox-outbox-patterns-and-saga-pattern-in-microservices-df65b66bf41d
[^2_12]: https://www.linkedin.com/posts/prem-s-bharti_how-to-build-a-real-time-order-tracker-using-activity-7333047115893415936-qH75
[^2_13]: https://medium.com/techno101/resiliency-patterns-in-microservice-architecture-e776977a1283
[^2_14]: https://medium.com/@rahul.lnmiit/designing-a-scalable-hotel-booking-system-an-in-depth-technical-guide-6e9c6e7340d9
[^2_15]: https://www.youtube.com/watch?v=4Td1ViGU5LA
[^2_16]: https://www.scribd.com/document/854283874/Order-Status-Feed-WS-API-Doc-V1-1-1
[^2_17]: https://www.linkedin.com/posts/sai-kiran-m-b719992b3_springboot-java-microservices-activity-7360807508849897473-D_y8
[^2_18]: https://arjonline.org/papers/arjcsit/v8-i1/5.pdf
[^2_19]: https://github.com/swaminathanvetri/reactor-copilot-handson-series-demo/issues/2
[^2_20]: https://medium.com/@jamala.zawia/designing-a-layered-websocket-architecture-for-scalable-real-time-systems-1ba3591e3ffb
[^2_21]: https://www.youtube.com/watch?v=2WYjtfRyHzQ
+27
View File
@@ -0,0 +1,27 @@
The fuck do we need:
Other things:
1. API gateway
1. Identity provider (separete service btw)
2. Service registry & discovery (also separate)
2. Notifications
3. Payment
4. User profile
5. Vehicle service
6. Admin service
7. Real-time status service (web-socket)
8. Order service
Shop:
1. Shoping cart
2. Goods (Catalog)
3. Inventory
Service:
1. Appoitment (booking)
2. Workshop (Capacity, etc.)
3. Service catalog
4. Staff service