Пять лет назад я вёл монолитное приложение на пару миллионов строк, и оно работало. Медленно релизилось, страшно деплоилось, но приносило деньги. А потом на очередном стратегическом совещании прозвучало слово, после которого всё пошло не так: «нам нужны микросервисы». Мы кивнули, нарисовали красивую схему на доске и решили, что через полгода будем летать. Летать не получилось — получилось выкапывать из продакшена последствия своих же решений и считать убытки. Ниже пять ошибок, которые обошлись нам, по моим скромным подсчётам, в несколько миллионов рублей и примерно в год чьей-то жизни.
Первая ошибка — мы нарезали сервисы по техническим слоям, а не по бизнес-возможностям. Получились сервис базы данных, сервис бизнес-логики, сервис API. Формально это микросервисы, а по факту — тот же монолит, только теперь каждый вызов идёт по сети и падает отдельно. Мы назвали это распределённым монолитом и очень гордились архитектурой, пока не поняли, что любая фича требует синхронного изменения во всех трёх сервисах и одновременного релиза. Правильный ориентир был простым: граница сервиса должна совпадать с границей бизнес-ответственности, у которой есть свой владелец и свои метрики.
Вторая ошибка — общая база данных. Мы не смогли отказаться от удобства и оставили все сервисы на одной схеме, «чтобы было проще делать отчёты». Через полгода никто не знал, кто и когда менял таблицу заказов, а любая миграция превращалась в переговоры между пятью командами. Разделение данных — это самая дорогая и самая непопулярная часть перехода, и именно её хочется отложить на потом. Не откладывайте. Каждый сервис должен владеть своими данными, а всё остальное общаться через события или явные контракты.
Третья ошибка — мы посчитали только разработку. В смете были команды и сроки, но не было распределённого трейсинга, централизованных логов, нормального CI с быстрыми сборками, оркестратора и людей, которые это будут поддерживать. В монолите у нас был один деплой и одна точка отказа. В микросервисах появились десятки точек отказа и потребность видеть сквозной путь запроса через все сервисы. Инфраструктура съела больше бюджета, чем сам код, и это надо закладывать в проект с первого дня, а не «когда-нибудь потом».
Четвёртая ошибка — мы поверили, что архитектура сама сделает команды автономными. Закон Конвея никто не отменял: структура системы отражает структуру коммуникаций в компании. Если у вас один менеджер на три команды и релизный комитет, который согласует всё по вторникам, микросервисы не дадут вам скорости. Они дадут вам больше сущностей, которые нужно согласовывать. Автономия команды — это в первую очередь право выкатывать в прод без чужого разрешения, а не просто отдельный репозиторий.
Пятая ошибка — мода вместо задачи. Мы начали резать то, что прекрасно жило в монолите, и получили сетевые задержки там, где раньше был простой вызов функции. Пять сервисов там, где хватало модуля, — это не прогресс, а налог на архитектурную гордость. Мой вывод после всего этого простой: монолит — не грех, а отличная точка старта, и его надо делить по мере боли, а не по веянию. Признаки реальной боли измеримы: разные требования к масштабированию, разные команды с разными релизными циклами, разные требования к надёжности. Нет боли — нет смысла платить за сложность.
Если вы сейчас стоите перед выбором, начните с малого. Вынесите один сервис, самый независимый по данным и самый нагруженный по требованиям, и проживите с ним полгода. Настройте метрики, трейсинг и деплой до того, как напишете вторую строчку кода. Посчитайте честно не только разработку, но и эксплуатацию, найм, обучение и стоимость неопределённости. И обязательно оставьте путь назад — возможность вернуть кусок логики в монолит без великого переселения народов. Микросервисы — это не цель, а инструмент, и как любой инструмент он прекрасен в умелых руках и разрушителен в руках нетерпеливых.
А как у вас? Съели ли микросервисы ваш монолит, или вы всё ещё держите оборону и счастливы? Расскажите в комментариях, какой одной ошибкой вы бы поделились с теми, кто только собирается идти этим путём — вместе мы точно сэкономим кому-то несколько миллионов.
Первая ошибка — мы нарезали сервисы по техническим слоям, а не по бизнес-возможностям. Получились сервис базы данных, сервис бизнес-логики, сервис API. Формально это микросервисы, а по факту — тот же монолит, только теперь каждый вызов идёт по сети и падает отдельно. Мы назвали это распределённым монолитом и очень гордились архитектурой, пока не поняли, что любая фича требует синхронного изменения во всех трёх сервисах и одновременного релиза. Правильный ориентир был простым: граница сервиса должна совпадать с границей бизнес-ответственности, у которой есть свой владелец и свои метрики.
Вторая ошибка — общая база данных. Мы не смогли отказаться от удобства и оставили все сервисы на одной схеме, «чтобы было проще делать отчёты». Через полгода никто не знал, кто и когда менял таблицу заказов, а любая миграция превращалась в переговоры между пятью командами. Разделение данных — это самая дорогая и самая непопулярная часть перехода, и именно её хочется отложить на потом. Не откладывайте. Каждый сервис должен владеть своими данными, а всё остальное общаться через события или явные контракты.
Третья ошибка — мы посчитали только разработку. В смете были команды и сроки, но не было распределённого трейсинга, централизованных логов, нормального CI с быстрыми сборками, оркестратора и людей, которые это будут поддерживать. В монолите у нас был один деплой и одна точка отказа. В микросервисах появились десятки точек отказа и потребность видеть сквозной путь запроса через все сервисы. Инфраструктура съела больше бюджета, чем сам код, и это надо закладывать в проект с первого дня, а не «когда-нибудь потом».
Четвёртая ошибка — мы поверили, что архитектура сама сделает команды автономными. Закон Конвея никто не отменял: структура системы отражает структуру коммуникаций в компании. Если у вас один менеджер на три команды и релизный комитет, который согласует всё по вторникам, микросервисы не дадут вам скорости. Они дадут вам больше сущностей, которые нужно согласовывать. Автономия команды — это в первую очередь право выкатывать в прод без чужого разрешения, а не просто отдельный репозиторий.
Пятая ошибка — мода вместо задачи. Мы начали резать то, что прекрасно жило в монолите, и получили сетевые задержки там, где раньше был простой вызов функции. Пять сервисов там, где хватало модуля, — это не прогресс, а налог на архитектурную гордость. Мой вывод после всего этого простой: монолит — не грех, а отличная точка старта, и его надо делить по мере боли, а не по веянию. Признаки реальной боли измеримы: разные требования к масштабированию, разные команды с разными релизными циклами, разные требования к надёжности. Нет боли — нет смысла платить за сложность.
Если вы сейчас стоите перед выбором, начните с малого. Вынесите один сервис, самый независимый по данным и самый нагруженный по требованиям, и проживите с ним полгода. Настройте метрики, трейсинг и деплой до того, как напишете вторую строчку кода. Посчитайте честно не только разработку, но и эксплуатацию, найм, обучение и стоимость неопределённости. И обязательно оставьте путь назад — возможность вернуть кусок логики в монолит без великого переселения народов. Микросервисы — это не цель, а инструмент, и как любой инструмент он прекрасен в умелых руках и разрушителен в руках нетерпеливых.
А как у вас? Съели ли микросервисы ваш монолит, или вы всё ещё держите оборону и счастливы? Расскажите в комментариях, какой одной ошибкой вы бы поделились с теми, кто только собирается идти этим путём — вместе мы точно сэкономим кому-то несколько миллионов.