Вопрос проверяет понимание паттернов устойчивости в распределённых системах, необходимых для обеспечения отказоустойчивости цепочек вызовов между сервисами.
В архитектуре микросервисов сервисы часто вызывают друг друга, образуя цепочки зависимостей. Если один сервис начинает отвечать с задержкой или полностью падает, его вызывающие могут заблокироваться в ожидании ответа, исчерпать свои ресурсы (потоки, соединения) и также выйти из строя. Этот эффект домино и есть каскадный отказ.
Для борьбы с этим применяют несколько взаимодополняющих подходов:
В экосистеме Node.js/JavaScript популярной библиотекой для реализации этих паттернов является resilience или интеграция в клиенты (например, axios-retry). Рассмотрим упрощённый пример с Circuit Breaker:
// Пример концепции Circuit Breaker
class CircuitBreaker {
constructor(request, failureThreshold, resetTimeout) {
this.request = request;
this.failureThreshold = failureThreshold; // e.g., 5
this.resetTimeout = resetTimeout; // e.g., 10000 ms
this.state = 'CLOSED';
this.failureCount = 0;
this.nextAttempt = Date.now();
}
async fire() {
if (this.state === 'OPEN') {
if (Date.now() > this.nextAttempt) {
this.state = 'HALF_OPEN';
} else {
throw new Error('Circuit breaker is OPEN');
}
}
try {
const response = await this.request();
this.success();
return response;
} catch (err) {
this.fail();
throw err;
}
}
success() {
this.failureCount = 0;
this.state = 'CLOSED';
}
fail() {
this.failureCount++;
if (this.failureCount >= this.failureThreshold) {
this.state = 'OPEN';
this.nextAttempt = Date.now() + this.resetTimeout;
}
}
}
// Использование
const unstableRequest = async () => { /* вызов к внешнему сервису */ };
const breaker = new CircuitBreaker(unstableRequest, 5, 10000);
// Обёрнутый вызов будет защищён
breaker.fire().then(handleSuccess).catch(handleFallback);Эти паттерны часто применяются вместе. Например, клиент с настроенным таймаутом и логикой повторных попыток оборачивается в Circuit Breaker, а все вызовы выполняются через выделенный пул соединений (Bulkhead).
Вывод: Применение паттернов устойчивости (Circuit Breaker, Retry, Timeout, Bulkhead, Fallback) критически важно для построения отказоустойчивых микросервисных систем. Они позволяют изолировать сбои, предотвратить их распространение по цепочке и сохранить работоспособность системы в целом, даже когда некоторые её части временно недоступны.