Все части монолита стали независимыми микросервисами, и эти микросервисы должны сообщаться между собой. Если раньше, находясь внутри одного процесса, сервисы вызывали методы друг друга напрямую, то теперь нужно интегрироваться.
Из четырёх способов интеграции[62] в микросервисной архитектуре обычно не используют обмен файлами и стараются не использовать shared database[63], зато активно работают с RPC и очередью сообщений.
Получается, все части монолита распались на микросервисы, а их обратно соединили паутиной синхронных и асинхронных вызовов (рис. 40).
Рис. 40. Множество микросервисов создают путаницу на архитектуре
По факту получился тот же монолит, но с бо́льшим количеством новых проблем.
Прямые связи между микросервисами усложняют анализ проблем. Например, запрос может пройти через пять микросервисов прежде, чем вернуться с ответом. Что, если на третьем микросервисе запрос завис? Что, если там была ошибка? Что, если на втором шаге должно было создаться сообщение в очередь, но оно не появилось? Возникает сложность с разбором проблем.
Эта проблема усложняется, если у микросервиса много экземпляров. Тогда добавляется еще одна ситуация: запрос может прийти на зависший экземпляр микросервиса.
Архитектуру сложно понять, и чем больше сервисов вы добавляете, тем запутанней всё становится. Добавление новых сервисов нелинейно повышает сложность архитектуры.
Неизвестно, кто потребители вашего API, что добавляет сложности в проектировании API и его изменении.
Если вы сразу начали с этого решения или остановились на нём во время пути рефакторинга монолита, то вполне резонно сделаете вывод, что с монолитом было лучше и дешевле.