Компьютерные сети
Resilience Patterns
В распределённых системах failure - не исключение, а норма. Сеть ненадёжна, сервисы падают, latency варьируется. Resilience patterns - это как иммунная система: не предотвращают болезни, но помогают быстро восстанавливаться.
- **Netflix Hystrix**: circuit breaker и bulkhead для сотен микросервисов, изолирующие failures
- **AWS SDK**: встроенный exponential backoff с jitter для всех API calls
- **Stripe API**: рекомендует idempotency keys + retry для payment operations
Предварительные знания
Circuit Breaker
**Circuit Breaker** - паттерн защиты от каскадных сбоев. Если сервис недоступен, circuit breaker "размыкает цепь" и сразу возвращает ошибку, не перегружая failing сервис запросами.
**Fail fast** - главное преимущество. Вместо 30-сек timeout на каждый запрос, circuit breaker возвращает ошибку мгновенно. Это освобождает ресурсы и предотвращает cascading failure.
Параметры: **failure threshold** (5 failures → open), **timeout** (30 сек в open state), **success threshold** (3 успеха в half-open → closed). Библиотеки: Resilience4j (Java), Polly (.NET), opossum (Node.js).
Сервис отвечает за 100ms в 99% случаев, но при сбое timeout 30 секунд. Как circuit breaker помогает?
Retry Strategies
**Retry** - повторение failed запроса. Не все ошибки стоит ретраить: transient errors (network glitch, 503) - да, permanent errors (404, 400) - нет. Важно не создать retry storm.
**Idempotency** критична для retry. GET/PUT/DELETE обычно идемпотентны. POST может создать duplicate - нужен idempotency key (Stripe: Idempotency-Key header).
Retry budget: ограничивайте процент retry запросов (например, max 10% от общего трафика). Без бюджета retry может удвоить/утроить нагрузку на struggling сервис.
Какой HTTP ответ НЕ стоит ретраить?
Exponential Backoff
**Exponential Backoff** - delay между retry растёт экспоненциально: 1s, 2s, 4s, 8s... Это даёт сервису время восстановиться вместо немедленных retry, создающих ещё больше нагрузки.
**AWS рекомендует** exponential backoff с base 100ms и max 20s для API calls. Google Cloud использует аналогичную стратегию с initial 1s.
Почему exponential backoff лучше constant delay для retry?
Jitter
**Jitter** - случайное отклонение в delay. Без jitter все клиенты ретраят одновременно (thundering herd), создавая spike нагрузки. Jitter размазывает retry во времени.
**AWS study** показало, что decorrelated jitter даёт лучший recovery time при высокой contention. Full jitter близок, но может давать слишком короткие delays.
1000 клиентов получили ошибку одновременно. Без jitter с 2s delay что произойдёт?
Bulkhead Pattern
**Bulkhead** - изоляция failure domains. Как отсеки в корабле: пробоина в одном отсеке не топит весь корабль. В софте: отдельные thread pools, connection pools, rate limits для разных сервисов.
**Hystrix** (Netflix) популяризировал bulkhead. Современные альтернативы: Resilience4j, Istio (service mesh level isolation), Envoy (connection pool limits).
Retry всегда улучшает reliability - чем больше retry, тем лучше
Aggressive retry без backoff и jitter может усугубить проблему: overloaded сервис получает ещё больше нагрузки. Правильная стратегия: exponential backoff + jitter + retry budget + circuit breaker
Без throttling retry создаёт positive feedback loop: сервис перегружен → retries → ещё больше нагрузки → ещё хуже. Circuit breaker останавливает этот цикл, давая сервису время восстановиться.
Как bulkhead предотвращает cascading failure?
Итоги
- **Circuit Breaker**: fail fast при failing сервисе, предотвращает cascading failure
- **Retry**: только для transient errors, с idempotency keys для non-idempotent operations
- **Exponential Backoff**: растущий delay даёт сервису время восстановиться
- **Jitter**: рандомизация предотвращает thundering herd при массовом retry
- **Bulkhead**: изоляция ресурсов - failure в одном домене не влияет на другие
Связанные темы
Resilience patterns - часть distributed systems design:
- Distributed Systems Intro — Fallacies of distributed computing - почему resilience важна
- Rate Limiting — Complementary pattern - защита от overload
- System Design Cases — Применение resilience в real-world архитектурах
Вопросы для размышления
- Как выбрать параметры circuit breaker (failure threshold, timeout)?
- Когда fallback (degraded mode) лучше чем fail fast?
- Как тестировать resilience patterns? (Chaos engineering, fault injection)