Кейс: цикл с HTTP-вызовом на каждый заказ — N+1, только не в JPA

Сервис заказов после разделения на микросервисы стал звать сервис пользователей, чтобы отдать имя покупателя в каждой строке списка. Код выглядел безопасно: fetch join убрали, JPA тут ни при чём, лишних SQL-запросов в базе нет.

Проблема была в цикле по списку заказов, где на каждый order шёл отдельный HTTP-вызов к user-service за именем. Список из 200 заказов на странице превращался в 200 последовательных запросов по сети — та же самая механика N+1, которую обычно ищут в Hibernate, воспроизвелась поверх HTTP.

for (Order order : orders) { User user = userClient.getUser( order.getUserId()); order.setUserName( user.getName()); }

Правили не кэшем и не async — заменили цикл на один batch-вызов userClient.getUsers(ids), который отдаёт мапу id → user за один round-trip. Кэш на уровне запроса решил бы только повторные заказы одного юзера, а не проблему N+1 как таковую.

Финал: N+1 — это паттерн доступа к данным, а не особенность конкретной технологии, он воспроизводится в любом месте, где есть цикл и вызов зависимости внутри.

Тренажёр: 600 вопросов, мок с таймером, план повторов

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки