Когда делить монолит: вопросы важнее хайпа
Микросервисы - популярный ответ на вопрос о масштабировании. Но правильный вопрос не 'делить или нет', а 'зачем и когда'.
Разговор о переходе с монолита на микросервисы в технологических командах идёт уже несколько лет. Для многих инженеров это звучит как очевидный следующий шаг. Для многих владельцев бизнеса - как дорогостоящий технический проект с непонятной отдачей.
Обе стороны по-своему правы. Проблема не в том, что микросервисы - плохая идея. Проблема в том, что вопрос "разделить монолит?" часто задаётся раньше, чем вопрос "зачем?"
Что на самом деле продаёт идею разделения
Обычно я слышу несколько аргументов за переход. Они звучат убедительно, но стоит их проверить.
"Мы не можем масштабироваться." Часто это означает, что одна часть системы перегружена, а остальные нет. Монолит не позволяет масштабировать части независимо. Это реальная проблема - но решается она разделением только тогда, когда нагрузка действительно не помещается на одну машину. Большинство компаний до этого предела не доходят.
"Релизы блокируют друг друга." Команды мешают друг другу вносить изменения. Это скорее организационная проблема, чем архитектурная. Разделение на сервисы может помочь, но только если одновременно разделить и зоны ответственности команд. Иначе - те же конфликты, просто в другой форме.
"Это модно и правильно." Это не аргумент. Netflix, Amazon и Google строили микросервисы потому что монолит у них уже не справлялся с нагрузкой и количеством команд. Это не тот же аргумент для компании с пятьюдесятью разработчиками.
Что реально усложняется после разделения
Распределённые системы сложнее монолита. Это не мнение - это факт.
- Отладка ошибок, которые возникают на стыке сервисов, занимает больше времени.
- Сетевые вызовы между сервисами добавляют задержки и точки отказа, которых в монолите нет.
- Управление данными между сервисами требует дополнительного проектирования - кто владеет каким данными, как обеспечивается согласованность.
- Развёртывание и мониторинг десяти сервисов сложнее, чем одного.
Я не говорю, что это непреодолимо. Я говорю, что это стоит дополнительных денег и времени, которые нужно заложить в план.
Признаки, что разделение действительно нужно
Несколько ситуаций, когда аргументы в пользу разделения становятся конкретными:
- есть один компонент, который перегружается и требует отдельного масштабирования, а всё остальное работает нормально;
- несколько независимых команд постоянно конфликтуют из-за кодовой базы и задерживают релизы друг друга - при этом зоны ответственности уже разделены организационно;
- часть системы требует другого уровня безопасности или надёжности, чем остальная;
- есть компонент с другим технологическим стеком, который невозможно вписать в общую кодовую базу.
Если ни один из этих пунктов не описывает текущую ситуацию - проблема скорее всего не в архитектуре.
Вопросы перед принятием решения
- Какая конкретная проблема делает текущую архитектуру недостаточной?
- Если сделать разделение - как изменится эта конкретная проблема и как мы это измерим?
- Кто будет владеть каждым сервисом - конкретная команда с чёткой ответственностью?
- Готова ли инфраструктура и экспертиза для обслуживания распределённой системы?
- Каков план на переходный период - как жить во время разделения, не останавливая развитие продукта?
Хорошая архитектура - это не модная архитектура. Это та, которая решает актуальную проблему с приемлемой стоимостью обслуживания.