Какие доводы и обстоятельства влияют на решение о делении или объединении сервисов
Что проверяют
Умеете ли вы принимать архитектурное решение по признакам, а не по моде «всё на микросервисы». Хороший ответ показывает, что граница сервиса проводится по бизнес-домену и данным, а не по слоям кода. Следом обычно просят пример: что вы бы разделили или, наоборот, склеили в своём последнем проекте.
Как отвечать
Разложите доводы на две группы. За деление:
- разная нагрузка: одна часть упирается в CPU или получает в десятки раз больше запросов, и её хочется масштабировать отдельно;
- разный темп изменений: модуль релизится каждый день, остальное раз в месяц, и общий деплой тормозит всех;
- владение: у куска есть своя команда, и закон Конвея всё равно проведёт границу по ней;
- изоляция отказов и требований: платёжная часть с жёсткими требованиями к безопасности не должна падать вместе с рекомендациями.
За объединение:
- болтливость: на каждый пользовательский запрос сервисы делают по несколько синхронных вызовов друг к другу по gRPC, задержки и точки отказа складываются;
- общие данные и транзакции: если операция атомарно меняет данные обоих сервисов, вы получаете саги и компенсации там, где хватило бы одной транзакции в базе;
- совместный деплой: сервисы всегда выкатываются вместе, значит это распределённый монолит;
- цена эксплуатации: каждый сервис это свой пайплайн, мониторинг, трейсинг и версии контрактов в
.proto.
Для Go стоит добавить, что модульный монолит здесь дёшев: пакеты в internal/, один бинарник, границы через интерфейсы. Такой модуль потом выносится в отдельный сервис почти без переписывания, если нужда станет реальной.
Где спотыкаются
Режут по техническим слоям: отдельный сервис «для базы», отдельный «для валидации». Получается сеть вызовов на каждый запрос без какой-либо независимости.
Не упоминают данные. Два сервиса с общей базой и общими таблицами не независимы, как бы их ни деплоили.
Говорят только о плюсах деления и не называют цену: сетевые ошибки, ретраи, идемпотентность, согласованность в конечном счёте, сложность локальной отладки.