Как устроена архитектура сервисов и взаимодействие между ними?
Что проверяют
Умеете ли вы рассуждать про распределённую систему, а не только про код одного сервиса. Ключевой сигнал: понимаете ли вы, что вызов соседнего сервиса может не ответить, ответить дважды или ответить через минуту.
Как отвечать
Сначала о границах. Сервисы режутся по бизнес-областям, у каждого своя база, общая база на два сервиса убивает независимость: схему уже не поменять в одиночку. Скажите, что монолит это нормальный старт, а микросервисы окупаются, когда команд много и они мешают друг другу в релизах.
Дальше два способа связи:
- синхронный (REST, gRPC): вызывающий ждёт ответа. Просто и понятно, но связывает доступность, упал сосед и упали вы. Обязательны таймаут, ограниченные ретраи и предохранитель (circuit breaker), иначе очередь ожидающих запросов кладёт сервис целиком;
- асинхронный (Kafka, RabbitMQ): событие публикуется, подписчики обрабатывают его когда смогут. Даёт устойчивость и разгружает пики, но приносит согласованность в конечном счёте, дубли доставки и необходимость идемпотентных обработчиков.
Назовите практики, которые всегда спрашивают следом: контракты и их версионирование, чтобы не ломать потребителей, идемпотентность по ключу запроса, транзакционный outbox, чтобы запись в базу и отправка события не разъезжались, сага вместо распределённой транзакции, сквозной идентификатор запроса и трассировка для разбора инцидентов.
Про Python уместно добавить, где это живёт: FastAPI или gRPC для синхронного слоя, aiokafka или Celery для фоновой обработки, а тяжёлые задачи всегда уводятся из запроса в очередь.
Где спотыкаются
Отвечают «микросервисы лучше монолита» без условия. Сильный ответ называет цену: сеть, эксплуатация, отладка, распределённые данные.
Забывают про таймауты и ретраи. Ретрай без ограничения и без идемпотентности превращает всплеск нагрузки в отказ и в дубли записей.
Не могут сказать, как искать причину, когда запрос прошёл через четыре сервиса. Ответ ждут про трассировку и корреляцию логов.