Пропускная способность пути отказа · 18 июля 2026 г.
Хаос-тестирование 429, повторов и изоляции арендаторов до потери выручки
Зависимость может замедлиться, вернуть 429, сбросить соединение, продублировать callback или восстанавливаться неравномерно. Превращаем эти сбои в контролируемые тесты retry budgets, idempotency, очередей, circuit breakers, bulkheads арендаторов и риска для выручки.
Методика
Что именно сравнивается
- Вводим по одному сбою под steady-нагрузкой, затем добавляем восстановление и ограниченный комбинированный тест.
- Измеряем HTTP-статус вместе с попытками вызовов, полезными завершениями, повторами, возрастом очереди, влиянием на арендаторов и временем восстановления.
- Используем пример усиления повторов Google SRE и семантику статусов IETF как документированные доказательства; значения выручки — явная модель.
- Запускаем сбои только в изолированном контуре с детерминированными двойниками провайдеров и проверенным teardown.
429 — управляющий сигнал, а не обычная ошибка
RFC 6585 определяет 429 Too Many Requests для ограничения скорости и допускает заголовок Retry-After со временем ожидания. Клиент, который немедленно повторяет запрос, превращает защитный сигнал провайдера в дополнительную нагрузку.[1]
Безопасная политика классифицирует сбои. Ошибка валидации постоянна. 429 можно повторить после задержки провайдера. При timeout состояние побочного эффекта неизвестно. 503 может означать перегрузку. Частично переданный поток иногда невозможно незаметно воспроизвести.
Timeout должен укладываться в бюджет пользовательской операции. Повторы должны быть ограничены, использовать экспоненциальный backoff с jitter и происходить на одном выбранном слое. AWS документирует эти шаблоны, потому что синхронные повторы способны превратить небольшой сбой в полную аварию.[3][4]
| Сбой | Действие по умолчанию | Доказательство | Опасная реакция |
|---|---|---|---|
| 429 + Retry-After | Ждать, добавить jitter, ограниченно повторить | Задержка, попытки, конечный результат | Немедленный параллельный повтор |
| Timeout | Отменить в бюджете операции; проверить состояние при возможных эффектах | Deadline и удалённый исход | Считать, что ничего не произошло |
| 500 / 503 | Повторять только идемпотентную работу с бюджетом | Состояние провайдера и попытки | Повторять на каждом слое |
| Сброс соединения | Классифицировать по фазе операции | Переданные/полученные байты и idempotency key | Слепо дублировать POST |
| Повреждённый успех | Безопасно отказать и сохранить класс ответа | Ошибка схемы | Считать HTTP 200 успехом |
| Медленное восстановление | Проверять постепенно; сохранять admission control | Полезный throughput и насыщение | Выпустить сразу всю очередь |
Повторы умножаются между слоями
Google SRE приводит конкретное предупреждение: если слои базы, backend, frontend и JavaScript делают по четыре попытки, одно действие пользователя может создать 64 обращения к базе. Повторы на нескольких слоях умножают попытки, а не складывают их.[2]
Та же глава моделирует backend на 10 000 QPS, получающий 10 100 QPS. Сто отклонённых запросов повторяются, поднимая следующую секунду до 10 200; retry-нагрузка растёт, пока полезная работа с первой попытки сокращается. Retry budget ограничивает это усиление.
График воспроизводит документированную мультипликативную структуру, а не наблюдавшийся инцидент клиента CapacityLab.
Один шумный арендатор не должен занять всех workers
Общие пулы соединений, очереди workers, квоты model-провайдера и retry budgets связывают арендаторов между собой. Один клиент, перегружающий дорогой метод, может занять concurrency, нужную несвязанным клиентам, даже когда их собственный трафик обычный.
Bulkheads разделяют дефицитные ресурсы. Concurrency, вместимость очереди, бюджеты токенов по арендаторам и справедливое планирование сохраняют перегрузку локальной. Общий admission control всё равно защищает сервис при достижении суммарной безопасной capacity.
Idempotency не даёт повтору стать второй покупкой или задачей. Stripe сохраняет первый результат для idempotency key, а AWS описывает идентификаторы клиентских запросов как основу безопасно повторяемых API.[6][5]
- Лимиты concurrency по операциям до общего пула зависимости.
- Очередь и retry budgets по арендаторам со справедливым планированием.
- Idempotency keys, сохраняющиеся через timeout и рестарт worker.
- Состояние circuit breaker, которое не синхронизирует всех callers в один шторм проб.
- Dead-letter и expiry для работы, которая уже не выполнит обещание пользователю.
Переведите сбой в риск для выручки
Технический error budget становится полезным для решений, когда связан с продуктовыми операциями. Если каждую минуту приходит 120 операций с маржинальным доходом $18, полный пятнадцатиминутный простой создаёт риск $32 400. Это не зафиксированный убыток: повторы, отложенная конверсия, возвраты и восстановление клиентов меняют итог.
Цель модели — расстановка приоритетов. 429 при преобразовании изображения может ухудшить представление; 429 при подтверждении платежа способен удерживать товар и выручку. Fault tests должны следовать критичности бизнеса, а не моде инфраструктуры.
Grafana k6 документирует xk6-disruptor для fault injection, а Google SRE прямо рекомендует проверять перегрузку и graceful degradation. Запускайте steady-трафик до сбоя, во время него и через восстановление.[7][2]
Реестр источников
Спецификации и цены меняются. Ссылки делают снимок проверяемым.
Источники и коммерческие данные проверены 2026-07-18. Если источник не говорит обратного, цены указаны без налогов.
- RFC 6585: 429 Too Many Requests ↗RFC Editor · продукт
- Addressing cascading failures ↗Google SRE · исследование
- Timeouts, retries, and backoff with jitter ↗Amazon Web Services · продукт
- Retry behavior in AWS SDKs ↗Amazon Web Services · продукт
- Making retries safe with idempotent APIs ↗Amazon Web Services · продукт
- Idempotent requests ↗Stripe · продукт
- Inject faults with xk6-disruptor ↗Grafana Labs · продукт
- k6 thresholds ↗Grafana Labs · продукт