Как улучшить архитектуру для избежания таймаутов и повышения устойчивости системы
Что проверяют
Понимаете ли вы, откуда берутся таймауты и как один медленный сервис роняет всю цепочку. Интервьюеру важна логика: сначала найти причину, потом ставить защиту. Следом дают сценарий «зависимость отвечает 30 секунд, что станет с вашим сервисом».
Как отвечать
Начните с диагностики. Трейсинг (OpenTelemetry) покажет, какой вызов в цепочке тянет время, а метрики пулов (потоки Tomcat, соединения HikariCP) покажут, что именно заканчивается первым.
Дальше меры:
- явные таймауты везде: connect и read у HTTP-клиента,
connectionTimeoutв HikariCP (по умолчанию 30 секунд), таймауты запросов к базе. Их согласуют по цепочке: если клиент ждёт 2 секунды, внутреннему вызову нельзя давать 5; - circuit breaker: Resilience4j размыкает цепь после порога ошибок или медленных вызовов и сразу отдаёт fallback;
- bulkhead: отдельный пул или лимит конкурентности на каждую зависимость, чтобы медленный сервис рекомендаций не съел потоки, нужные оплате;
- retry с экспоненциальной задержкой и джиттером: только для идемпотентных операций и с общим лимитом, иначе повторы добивают и так больной сервис;
- асинхронность: всё, что не нужно пользователю в ответе, уходит в очередь (Kafka, RabbitMQ). Виртуальные потоки Java 21 снимают проблему нехватки потоков при блокирующем I/O, но саму зависимость не ускоряют;
- деградация: кеш последнего удачного ответа, страница без некритичного блока;
- ограничение входа: rate limiting и быстрый
503при перегрузке лучше очереди, в которой все запросы умирают по таймауту.
Проверяют это нагрузочными тестами с искусственной задержкой на зависимости.
Где спотыкаются
Предлагают просто увеличить таймаут. Это прячет симптом: потоки заняты дольше, пул кончается быстрее, и отказ становится каскадным.
Ставят retry на каждом уровне цепочки. Три уровня по три попытки дают до 27 запросов к нижнему сервису на один пользовательский, и тот падает окончательно.
Называют паттерны без параметров. Circuit breaker без порога, окна подсчёта и понятного поведения в полуоткрытом состоянии звучит как заученное слово. Сильнее, когда вы говорите, что именно вернёт fallback пользователю.