Отказоустойчивость — это не «поставить ретраи», а набор осознанных решений на каждом уровне сервиса. Разберём паттерны, которые удерживают систему живой под нагрузкой и при частичных отказах.
С чего начинается устойчивость
и понять, какие отказы допустимы. Устойчивый сервис деградирует предсказуемо: теряет функциональность частями, а не падает целиком.
- Таймауты и дедлайны — ни один вызов не должен «висеть» бесконечно.
- Ретраи с backoff — повтор только для идемпотентных операций.
- Circuit breaker — отсекаем зависимость, которая уже недоступна.
- Очереди и буферизация — сглаживаем пики нагрузки.
Пример: контекст с дедлайном
// ограничиваем время вызова зависимостиctx, cancel := context.WithTimeout(ctx, 200*time.Millisecond)defer cancel() resp, err := client.Do(ctx, req)if err != nil { // деградация вместо падения return fallback(), nil}Дальше эти решения удобно собрать в единую схему сервиса — чтобы видеть все точки отказа и пути деградации целиком.
Что запомнить
Отказоустойчивость проектируется, а не добавляется постфактум. Начните с дедлайнов и деградации, затем добавляйте circuit breaker и очереди — и проверяйте гипотезы на модели, прежде чем внедрять их в код.