Монолит и микросервисы
Интернет-магазин, восемь команд, один репозиторий, одна база. Команда доставки готова выкатить свою правку во вторник, но в общей ветке лежит недоделанный каталог - и поезд стоит. Через год ту же систему режут на восемь сервисов: каждая команда катит когда хочет, зато собрать один экран теперь стоит пяти сетевых запросов. Вот этот размен и обсуждают на собеседовании.
Стержень: микросервисы покупают независимость выпуска и платят за неё сетью. Границы ведут по бизнес-областям, не по техническим слоям.
// Формулировки: «чем микросервисы отличаются от монолита?», «как нарезать систему?», «требование задело четыре сервиса»
Один поезд или восемь
Монолит выкатывают целиком. Восемь команд, каждая хочет катить дважды в неделю - шестнадцать выкатов общего кода, и красный тест любой из них держит остальные семь. Дата релиза становится общим ресурсом, за который торгуются на созвонах.
Независимость развёртывания - возможность выпустить свою часть, не согласовывая момент выката с соседями. Это главное отличие микросервисов, всё остальное - следствия. И оно же объясняет, почему архитектуру часто выбирают под структуру команд, а не под нагрузку.
// Цена независимости видна не в коде, а в эксплуатации: восемь конвейеров сборки, восемь наборов метрик, восемь дежурств. На две команды это накладные расходы без выгоды.
Чем платят: вызов функции стал запросом по сети
Внутри монолита корзина зовёт склад обычным вызовом функции - единицы наносекунд, и он не умеет «не ответить». После разреза тот же вызов идёт по сети: примерно полмиллисекунды внутри одного дата-центра, то есть в сотни тысяч раз дольше. Плюс он теперь умеет отвалиться, зависнуть и выполниться дважды.
Дальше считаем доступность. Экран собирается из пяти сервисов, у каждого доступность 99,9 процента. Экран работает, только когда работают все пятеро: 0,999 в пятой степени - это 0,995, то есть 99,5 процента. В часах за год: у одного сервиса простой 8,8 часа, у экрана - около 44 часов. Разрезал систему на пять частей и получил впятеро больше простоя, ничего при этом не сломав.
// Отсюда растут сквозная трассировка, повторы, таймауты и вечный вопрос «кто из пятерых тормозил». В монолите этой работы нет вообще - там ответ виден в одном стеке вызовов.
- сквозная трассировка
- общий идентификатор запроса, по которому видно его путь через все сервисы и время в каждом
Границы ведут по бизнесу, а не по слоям
Нарезка по областям: платежи, каталог, доставка. Правка «добавить скидку по промокоду» живёт внутри платежей - один сервис, одна команда, один выкат.
Нарезка по слоям: сервис интерфейса, сервис логики, сервис доступа к данным. Та же скидка требует правки во всех трёх и согласованного релиза. Сложность распределённой системы получена, независимость выпуска - нет. У этого есть имя: распределённый монолит, худший из вариантов.
// Тот же эффект даёт общая таблица на два сервиса. Схема базы превращается в контракт, о котором никто не договаривался: переименовал колонку - уронил соседа. Данными владеет один сервис, остальные ходят через его интерфейс.
Требование поперёк сервисов
«Показывать бонусные баллы в корзине» звучит на пять минут работы. Баллы живут в лояльности, корзина в заказах, списание в платежах, показ - в мобильном приложении. Четыре команды, четыре бэклога, четыре очереди на ревью.
Одновременный выкат четырёх сервисов - самый хрупкий план из возможных: задержка любой команды останавливает всех, а откатывать приходится вчетвером и в том же порядке. Спринт превращается в квартал не из-за объёма кода, а из-за синхронизации.
// Рабочий приём: разложить на шаги, каждый из которых полезен сам по себе и совместим с текущим поведением. Сначала лояльность отдаёт баллы наружу, потом заказы начинают их читать и молчать, потом показ включают признаком функциональности. Каждый шаг катится и откатывается отдельно.
- признак функциональности
- переключатель, который включает уже выкаченный код для части пользователей без нового релиза
Как отвечать: «Зачем аналитику вообще знать про границы сервисов?»
Чтобы называть цену требования до того, как его пообещали. Одно и то же по смыслу изменение внутри одного сервиса едет за спринт, а поперёк четырёх сервисов и трёх команд - это квартал, потому что нужен согласованный выкат, а он останавливается на самой медленной команде. Зная карту владения, я стараюсь формулировать требования так, чтобы не резать их поперёк границ, а если это неизбежно - сразу предлагаю последовательность самостоятельно полезных шагов вместо одновременного релиза. При этом выбор стека и способ разреза остаются за командой, я в них не лезу.
Кандидат объясняет пользу через сроки и планирование, приводит масштаб разницы и явно очерчивает границу своей ответственности.
На чём валятся
- −− Берут микросервисы на старте, когда границы предметной области ещё не понятны.
- −− Режут по техническим слоям и получают распределённый монолит.
- −− Разрешают двум сервисам писать в одну таблицу.
- −− Планируют одновременный выкат нескольких сервисов вместо цепочки совместимых шагов.
- −− Считают доступность сервиса, а не всей цепочки, из которой собран экран.
- −− Лезут в выбор технологий вместо работы с границами и сроками.
Проверьте себя
Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.
- По какому принципу разумно нарезать систему на сервисы?A)По слоям: интерфейс, логика, данныеB)По границам бизнес-областейC)По числу разработчиков в компанииD)По типам используемых баз данных
показать ответ и разбор
+B)По границам бизнес-областей// разбор: Границы сервисов ведут по областям предметной сферы: платежи, каталог, доставка. Тогда типовое изменение затрагивает один сервис, и команда владеет им целиком. Нарезка по техническим слоям даёт обратное: почти каждая доработка требует согласованного релиза всех трёх частей.
- Два сервиса пишут в одну таблицу общей базы. Чем это опасно?A)База не выдержит двойную нагрузкуB)Появится дублирование записей в таблицеC)Изменение схемы ломает оба сервиса сразуD)Транзакции перестанут работать корректно
показать ответ и разбор
+C)Изменение схемы ломает оба сервиса сразу// разбор: Общая таблица превращает схему базы в неявный контракт между командами: любое изменение колонки требует согласованного выпуска. Независимость развёртывания теряется, и получается распределённый монолит — сложность микросервисов без их выгод. Данными владеет один сервис, остальные ходят через его интерфейс.
- Стартап из пяти человек проектирует систему. Что обычно разумнее на старте?A)Сразу микросервисы, чтобы не переписыватьB)Монолит с ясными внутренними границамиC)Отдельный сервис на каждую сущностьD)Бессерверные функции на каждую операцию
показать ответ и разбор
+B)Монолит с ясными внутренними границами// разбор: Пока предметная область не устоялась, границы сервисов угадать невозможно, а ошибка в них обходится дороже всего. Монолит с аккуратными модулями позволяет двигать границы дёшево, а когда нагрузка и области определятся, выделить самые нагруженные части в сервисы.
- Зачем аналитику разбираться в границах сервисов?A)Чтобы выбирать технологии за командуB)Чтобы оценивать сроки вместо разработчиковC)Чтобы контролировать качество кодаD)Чтобы понимать, кого затрагивает требование
показать ответ и разбор
+D)Чтобы понимать, кого затрагивает требование// разбор: Границы определяют, сколько команд придётся согласовать и сколько релизов синхронизировать. Требование внутри одного сервиса едет за спринт, а то же требование поперёк четырёх сервисов превращается в квартальную историю. Аналитик, видящий карту, формулирует требования так, чтобы не резать их поперёк владения.
- Требование задевает четыре сервиса и три команды. Что предложит опытный аналитик?A)Разбить на этапы с самостоятельной ценностьюB)Отдать всё одной команде целикомC)Согласовать общий день релиза для всехD)Отложить до объединения сервисов
показать ответ и разбор
+A)Разбить на этапы с самостоятельной ценностью// разбор: Одновременный релиз четырёх сервисов — самый хрупкий из возможных планов: задержка у любой команды останавливает всех. Обычно удаётся выделить последовательность шагов, каждый из которых полезен сам по себе и совместим с текущим поведением, а переключение делается признаком функциональности.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.