← [Раздел](README.md) · [Главная](../README.md)

# Монолит vs микросервисы

## Цель

Научиться **осознанно выбирать** между монолитом, модульным монолитом и микросервисами: критерии разделения, данные, коммуникация и поэтапная миграция без остановки бизнеса.

## Предварительно

- [README раздела 11](README.md)
- Разделы про API, очереди, БД (04–06 курса)

## Время

~70 минут

---

## Классический монолит

Одно deployable-приложение, одна БД (часто), общий runtime.

| Плюсы | Минусы |
|-------|--------|
| Простая отладка | Масштабируется целиком |
| Транзакции ACID в одной БД | Страх менять «всё» |
| Один pipeline | Разные команды мешают друг другу |
| Низкий operational overhead | Технологический lock-in |

**Идеален для:** MVP, стартап до product-market fit, небольшие команды.

---

## Modular monolith

Монолит с **жёсткими границами модулей** внутри репозитория:

```text
src/
  orders/     ← публичный API модуля
  catalog/
  billing/
```

Правила:

- модули общаются через **публичные интерфейсы**, не через чужие таблицы;
- arch unit tests запрещают циклы;
- одна БД возможна, но **схемы по владельцу**.

Это часто **лучший следующий шаг**, чем сразу 15 микросервисов.

---

## Микросервисы

Независимо deployable сервисы вокруг **бизнес-возможностей** (bounded context).

| Плюсы | Минусы |
|-------|--------|
| Независимый scale и релиз | Распределённые транзакции |
| Разные стеки под задачу | Observability обязательна |
| Изоляция отказов (если сделано) | Contract tests, versioning |
| Автономия команд | DevOps зрелость |

**Не делите по слоям** (UI-сервис, DB-сервис) — это распределённый монолит.

---

## Как резать границы

| Хорошая граница | Плохая граница |
|-----------------|----------------|
| «Оформление заказа» | «Все SELECT к users» |
| «Каталог» | «Утилиты» |
| «Платежи» | «Всё что медленное» |

Проверка: может ли команда **изменить и задеплоить** сервис без согласования с пятью другими?

---

## Данные в микросервисах

| Паттерн | Описание |
|---------|----------|
| **Database per service** | У каждого сервиса своя БД |
| **Shared DB (анти)** | Общие таблицы — связность |
| **Saga** | Цепочка локальных транзакций + компенсации |
| **Outbox** | События надёжно из той же транзакции |
| **CQRS** | Разделение чтения и записи (сложно) |

Начните с **database per service** + события; saga — когда без распределённой транзакции никак.

---

## Синхрон vs асинхрон

| Sync HTTP/gRPC | Async (очередь, Kafka) |
|----------------|------------------------|
| Простой ментально | Слабая связность |
| Каскадные сбои | Eventual consistency |
| Нужны timeout, CB | Сложнее отладка |

Hot path пользователя — sync с защитой; побочные эффекты — async.

---

## Strangler Fig (удавливающая лиана)

1. Новый сервис принимает **новый** трафик (фича X).
2. API Gateway маршрутизирует `/api/v2/orders` → новый сервис.
3. Старый монолит **сужается**, пока не останется shell.
4. Данные мигрируют постепенно (dual write → read from new).

Годы — нормальный горизонт для крупной системы.

---

## Когда НЕ переходить на микросервисы

- Нет проблем с деплоем и scale монолита.
- Одна команда < 8 человек.
- Нет платформы (k8s, CI, observability).
- «Потому что модно».

---

## Чеклист решения

- [ ] Bounded contexts нарисованы на схеме
- [ ] Для каждого сервиса — владелец команды
- [ ] План данных (не shared tables)
- [ ] SLO и tracing заложены
- [ ] Путь отката миграции

---

## Самопроверка

1. Чем modular monolith лучше «хаотичного» монолита?
2. Что такое database per service?
3. Опишите strangler pattern в трёх шагах.
4. Почему «микросервис на каждую таблицу» — плохо?

---

## Дальше

→ [Serverless и FaaS](serverless-i-faas.md)  
← [README раздела 11](README.md)
