Programming

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

Монолит — приложение, собранное и развёрнутое одним куском; микросервисы — набор самостоятельных сервисов, которые деплоятся и масштабируются независимо.

Что такое монолит и микросервисы

Монолит (монолитная архитектура) — приложение, весь код которого собирается в один артефакт и разворачивается целиком: один процесс, одна база данных, один деплой. Вызовы между модулями — обычные вызовы функций внутри процесса.

Микросервисная архитектура — та же система, разрезанная на несколько самостоятельных сервисов. Каждый отвечает за свой кусок бизнес-логики (заказы, платежи, уведомления), владеет своими данными, деплоится отдельно и общается с остальными по сети — через REST, gRPC или брокер сообщений.

Микросервис — один такой сервис. Ключевой признак не размер («маленький»), а независимость: его можно выкатить в прод, не трогая остальные.

Сравнение

Монолит Микросервисы
Деплой Целиком, весь код сразу Каждый сервис отдельно
Масштабирование Только приложение целиком Точечно, узкие места
Отказ компонента Часто ложится всё Изолирован, если продумано
Транзакции Обычные ACID в одной БД Saga, eventual consistency
Отладка Стектрейс и отладчик Распределённый трейсинг
Стек Один на всю систему Свой у каждого сервиса
Вызов соседа Наносекунды, не падает Миллисекунды, таймауты, ретраи
Порог входа Низкий Kubernetes, CI/CD, мониторинг обязательны

Строка про масштабирование — главный практический аргумент. Если ресурсоёмкая часть одна (скажем, инференс модели), в монолите придётся клонировать всё приложение вместе с админкой и биллингом на дорогие GPU-инстансы. В микросервисах на GPU уезжает только сервис инференса, остальное живёт на обычных CPU-нодах.

Цена микросервисов

Сеть — не бесплатный вызов функции. То, что в монолите было user.get_balance(), становится HTTP-запросом, который может зависнуть, вернуть 503 или ответить через две секунды. Каждое такое место требует таймаутов, ретраев, идемпотентности и circuit breaker.

Данные разъезжаются. Один JOIN между заказами и пользователями превращается в два запроса и сборку в коде. Транзакция «списать деньги и создать заказ» перестаёт быть атомарной — нужна Saga с компенсирующими действиями.

Наблюдаемость становится обязательной. В монолите причину ошибки видно в стектрейсе; в микросервисах запрос проходит семь сервисов, и без сквозного trace id и централизованных логов расследование превращается в археологию.

Инфраструктура растёт. Двадцать сервисов — это двадцать пайплайнов, Docker-образов, наборов алертов и дежурств.

Distributed monolith — главный антипаттерн

Худший исход: сервисы разделили, а связи оставили. Признаки:

  • релиз требует выкатывать пять сервисов одновременно и в правильном порядке;
  • сервисы ходят в одну общую базу и правят чужие таблицы;
  • изменение поля в одном сервисе ломает три соседних;
  • локально ничего не поднимается без всего кластера.

Получилась распределённая система со всеми её сложностями, но без единственного бонуса — независимости деплоя. Это хуже обоих исходных вариантов.

Что выбрать

Монолит по умолчанию. Новый продукт, команда до 10–15 человек, границы предметной области ещё не понятны — режьте позже. Модульный монолит (чёткие модули с явными интерфейсами внутри одного деплоя) даёт большую часть дисциплины микросервисов без сетевых расходов.

Микросервисы, когда есть конкретная причина: несколько команд мешают друг другу в одном релизном поезде; части системы требуют принципиально разного железа или языка; какой-то компонент нужно масштабировать на два порядка сильнее остальных.

Типичный путь — не переписывание с нуля, а strangler fig: от монолита постепенно отрезают куски, ставят перед ним API Gateway и переводят трафик по частям. Код при этом часто остаётся в монорепозитории — микросервисы не обязывают заводить отдельный репозиторий на сервис.

Связанные термины

Готовы запустить GPU-задачу?

Запустить GPU-сервер