Вопрос проверяет знание паттернов, которые предотвращают перегрузку внешних сервисов и обеспечивают устойчивость системы.
При интеграции с внешними API или микросервисами всегда есть риск, что они станут медленными или недоступными, что может привести к каскадным сбоям в вашей системе. Для предотвращения этого используются несколько ключевых паттернов устойчивости (resilience patterns).
Этот паттерн отслеживает неудачные вызовы. При превышении порога ошибок "выключатель" размыкается, и все последующие вызовы немедленно завершаются ошибкой, не доходя до проблемного сервиса. Это даёт ему время на восстановление. Через некоторое время выключатель переходит в "полуоткрытое" состояние, пропуская пробные запросы.
// Псевдокод логики Circuit Breaker
if (circuitBreaker.isOpen()) {
throw new CircuitBreakerOpenException();
}
try {
response = callExternalService();
circuitBreaker.recordSuccess();
} catch (Exception e) {
circuitBreaker.recordFailure();
throw e;
}Вы ограничиваете количество запросов, которые ваше приложение отправляет внешнему сервису в секунду или минуту. Это защищает как ваш бэкенд от чрезмерной нагрузки, так и внешний сервис от ваших запросов. Популярные алгоритмы: Token Bucket, Leaky Bucket.
Для временных сбоев (например, таймаут сети) запрос можно повторить. Но делать это нужно с увеличивающейся задержкой (экспоненциальной или фиксированной), чтобы не создавать всплесков нагрузки на восстанавливающийся сервис.
// Пример экспоненциальной отсрочки
let delay = 100; // начальная задержка в мс
for (let attempt = 0; attempt < maxAttempts; attempt++) {
try {
return await callService();
} catch (error) {
if (!isTransientError(error)) throw error;
await sleep(delay);
delay *= 2; // Увеличиваем задержку
}
}У каждого вызова должен быть установлен разумный таймаут. Если ответ не пришёл за это время, вызов прерывается, освобождая ресурсы (потоки, соединения) в вашем приложении.
Идея заимствована из кораблестроения: изолируйте ресурсы для разных вызовов. Например, выделите отдельный пул потоков для запросов к платежному шлюзу и другой — для сервиса уведомлений. Проблема в одном не "утонет" все остальные.
Вывод: Эти паттерны стоит применять вместе в критически важных интеграциях, особенно в микросервисных архитектурах, чтобы обеспечить отказоустойчивость и предотвратить каскадные сбои. Библиотеки вроде Resilience4j для Java или Polly для .NET предоставляют готовые реализации.
Уровень
Рейтинг:
4
Сложность:
6
Навыки
Node.js
Networks
Ключевые слова
Подпишись на Java Developer в телеграм