сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · Архитектура

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

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

Интернет-магазин, восемь команд, один репозиторий, одна база. Команда доставки готова выкатить свою правку во вторник, но в общей ветке лежит недоделанный каталог - и поезд стоит. Через год ту же систему режут на восемь сервисов: каждая команда катит когда хочет, зато собрать один экран теперь стоит пяти сетевых запросов. Вот этот размен и обсуждают на собеседовании.

Стержень: микросервисы покупают независимость выпуска и платят за неё сетью. Границы ведут по бизнес-областям, не по техническим слоям.

// Формулировки: «чем микросервисы отличаются от монолита?», «как нарезать систему?», «требование задело четыре сервиса»

Один поезд или восемь

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

Независимость развёртывания - возможность выпустить свою часть, не согласовывая момент выката с соседями. Это главное отличие микросервисов, всё остальное - следствия. И оно же объясняет, почему архитектуру часто выбирают под структуру команд, а не под нагрузку.

// Цена независимости видна не в коде, а в эксплуатации: восемь конвейеров сборки, восемь наборов метрик, восемь дежурств. На две команды это накладные расходы без выгоды.

Чем платят: вызов функции стал запросом по сети

Внутри монолита корзина зовёт склад обычным вызовом функции - единицы наносекунд, и он не умеет «не ответить». После разреза тот же вызов идёт по сети: примерно полмиллисекунды внутри одного дата-центра, то есть в сотни тысяч раз дольше. Плюс он теперь умеет отвалиться, зависнуть и выполниться дважды.

Дальше считаем доступность. Экран собирается из пяти сервисов, у каждого доступность 99,9 процента. Экран работает, только когда работают все пятеро: 0,999 в пятой степени - это 0,995, то есть 99,5 процента. В часах за год: у одного сервиса простой 8,8 часа, у экрана - около 44 часов. Разрезал систему на пять частей и получил впятеро больше простоя, ничего при этом не сломав.

// Отсюда растут сквозная трассировка, повторы, таймауты и вечный вопрос «кто из пятерых тормозил». В монолите этой работы нет вообще - там ответ виден в одном стеке вызовов.

сквозная трассировка
общий идентификатор запроса, по которому видно его путь через все сервисы и время в каждом

Границы ведут по бизнесу, а не по слоям

Нарезка по областям: платежи, каталог, доставка. Правка «добавить скидку по промокоду» живёт внутри платежей - один сервис, одна команда, один выкат.

Нарезка по слоям: сервис интерфейса, сервис логики, сервис доступа к данным. Та же скидка требует правки во всех трёх и согласованного релиза. Сложность распределённой системы получена, независимость выпуска - нет. У этого есть имя: распределённый монолит, худший из вариантов.

// Тот же эффект даёт общая таблица на два сервиса. Схема базы превращается в контракт, о котором никто не договаривался: переименовал колонку - уронил соседа. Данными владеет один сервис, остальные ходят через его интерфейс.

Требование поперёк сервисов

«Показывать бонусные баллы в корзине» звучит на пять минут работы. Баллы живут в лояльности, корзина в заказах, списание в платежах, показ - в мобильном приложении. Четыре команды, четыре бэклога, четыре очереди на ревью.

Одновременный выкат четырёх сервисов - самый хрупкий план из возможных: задержка любой команды останавливает всех, а откатывать приходится вчетвером и в том же порядке. Спринт превращается в квартал не из-за объёма кода, а из-за синхронизации.

// Рабочий приём: разложить на шаги, каждый из которых полезен сам по себе и совместим с текущим поведением. Сначала лояльность отдаёт баллы наружу, потом заказы начинают их читать и молчать, потом показ включают признаком функциональности. Каждый шаг катится и откатывается отдельно.

признак функциональности
переключатель, который включает уже выкаченный код для части пользователей без нового релиза

Как отвечать: «Зачем аналитику вообще знать про границы сервисов?»

Чтобы называть цену требования до того, как его пообещали. Одно и то же по смыслу изменение внутри одного сервиса едет за спринт, а поперёк четырёх сервисов и трёх команд - это квартал, потому что нужен согласованный выкат, а он останавливается на самой медленной команде. Зная карту владения, я стараюсь формулировать требования так, чтобы не резать их поперёк границ, а если это неизбежно - сразу предлагаю последовательность самостоятельно полезных шагов вместо одновременного релиза. При этом выбор стека и способ разреза остаются за командой, я в них не лезу.

Кандидат объясняет пользу через сроки и планирование, приводит масштаб разницы и явно очерчивает границу своей ответственности.

На чём валятся

  • − Берут микросервисы на старте, когда границы предметной области ещё не понятны.
  • − Режут по техническим слоям и получают распределённый монолит.
  • − Разрешают двум сервисам писать в одну таблицу.
  • − Планируют одновременный выкат нескольких сервисов вместо цепочки совместимых шагов.
  • − Считают доступность сервиса, а не всей цепочки, из которой собран экран.
  • − Лезут в выбор технологий вместо работы с границами и сроками.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.

  1. #ana_arc_styles1 / 5
    По какому принципу разумно нарезать систему на сервисы?
    A)По слоям: интерфейс, логика, данные
    B)По границам бизнес-областей
    C)По числу разработчиков в компании
    D)По типам используемых баз данных
    показать ответ и разбор
    +B)По границам бизнес-областей

    // разбор: Границы сервисов ведут по областям предметной сферы: платежи, каталог, доставка. Тогда типовое изменение затрагивает один сервис, и команда владеет им целиком. Нарезка по техническим слоям даёт обратное: почти каждая доработка требует согласованного релиза всех трёх частей.

  2. #ana_arc_styles2 / 5
    Два сервиса пишут в одну таблицу общей базы. Чем это опасно?
    A)База не выдержит двойную нагрузку
    B)Появится дублирование записей в таблице
    C)Изменение схемы ломает оба сервиса сразу
    D)Транзакции перестанут работать корректно
    показать ответ и разбор
    +C)Изменение схемы ломает оба сервиса сразу

    // разбор: Общая таблица превращает схему базы в неявный контракт между командами: любое изменение колонки требует согласованного выпуска. Независимость развёртывания теряется, и получается распределённый монолит — сложность микросервисов без их выгод. Данными владеет один сервис, остальные ходят через его интерфейс.

  3. #ana_arc_styles3 / 5
    Стартап из пяти человек проектирует систему. Что обычно разумнее на старте?
    A)Сразу микросервисы, чтобы не переписывать
    B)Монолит с ясными внутренними границами
    C)Отдельный сервис на каждую сущность
    D)Бессерверные функции на каждую операцию
    показать ответ и разбор
    +B)Монолит с ясными внутренними границами

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

  4. #ana_arc_styles4 / 5
    Зачем аналитику разбираться в границах сервисов?
    A)Чтобы выбирать технологии за команду
    B)Чтобы оценивать сроки вместо разработчиков
    C)Чтобы контролировать качество кода
    D)Чтобы понимать, кого затрагивает требование
    показать ответ и разбор
    +D)Чтобы понимать, кого затрагивает требование

    // разбор: Границы определяют, сколько команд придётся согласовать и сколько релизов синхронизировать. Требование внутри одного сервиса едет за спринт, а то же требование поперёк четырёх сервисов превращается в квартальную историю. Аналитик, видящий карту, формулирует требования так, чтобы не резать их поперёк владения.

  5. #ana_arc_styles5 / 5
    Требование задевает четыре сервиса и три команды. Что предложит опытный аналитик?
    A)Разбить на этапы с самостоятельной ценностью
    B)Отдать всё одной команде целиком
    C)Согласовать общий день релиза для всех
    D)Отложить до объединения сервисов
    показать ответ и разбор
    +A)Разбить на этапы с самостоятельной ценностью

    // разбор: Одновременный релиз четырёх сервисов — самый хрупкий из возможных планов: задержка у любой команды останавливает всех. Обычно удаётся выделить последовательность шагов, каждый из которых полезен сам по себе и совместим с текущим поведением, а переключение делается признаком функциональности.

дальше

Теорию прочитали. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.