GH GambleHub

Тестирование устойчивости

1) Базовые понятия и цели

Надежность (reliability) — вероятность работоспособности; устойчивость (resilience) — поведение при и после сбоя.
SLO/ошибочный бюджет: критерии «приемлемости» деградации.
Steady-state hypothesis: формальное ожидание стабильных метрик (например, p95<200 мс, error rate<0.5%). Эксперимент считается успешным, если гипотеза выдержана.
Виды отказов: сетевые (латентность, потери/дубли, разрывы), вычислительные (CPU, память), сторидж (I/O, исчерпание диска), зависимостей (5xx, timeouts, rate-limit), логические (частичные инциденты, «медленная деградация»), операционные (релиз, конфиг), «темные» (split-brain, часовые смены).

2) Пирамида устойчивости

1. Юнит-тесты отказов логики (ретраи, идемпотентность, таймауты).
2. Компонентные с fault-inject адаптерами (Testcontainers/tc-netem).
3. Интеграционные/системные с сетью/БД/кэшами и real-world профилями.
4. Хаос-эксперименты в pre-prod (а затем ограниченно в проде) по runbook’ам.
5. Гейм-дей — сценарные учения команды (люди + инструменты).

3) Наблюдаемость как основа

SLI: латентность p50/p95/p99, error rate, saturation (CPU/heap/FD/IOPS), drop/timeout, queue depth.
Трассировки: для поиска «узких мест» под отказом.
Семантические метрики устойчивости: доля успешных graceful-degrade, доля shed-запросов, скорость самовосстановления (MTTR).
Маркировка экспериментов: `chaos.experiment_id`, `phase=inject/recover` в событиях/логах.

4) Каталог инъекций отказов (faults)

Сеть: задержка/джиттер, потеря/дубликаты/реордеринг, ограничение пропускной способности, пакетные «штормы», TLS-обрывы.
Хост: ограничение CPU, утечки/лимиты памяти, паузы GC, исчерпание дескрипторов, «clock skew».
Хранилище: рост латентности, EROFS, ENOSPC, деградация реплики, потеря лидера.
Зависимости: 5xx/429, замедление, флаппинг DNS, устаревшие сертификаты, rate-limit, «частичные ответы».
Данные: повреждение записи, «дырки» в потоках, дубли событий, конфликты версий.
Операции: неудачный релиз, фича-флаг, конфиг-дрейф, ручная ошибка (в рамках симуляции).

5) Паттерны устойчивости (что проверять)

Ретраи с джиттером и таймауты на каждом RPC.
Circuit Breaker (открытие/полуоткрытие, экспоненциальное восстановление).
Bulkheads (изоляция пулов/очередей на критичные домены).
Load Shedding (сбрасываем низкоприоритетные запросы при насыщении).
Backpressure (сигналы вверх по цепочке, лимиты параллелизма).
Idempotency (ключи идемпотентности на «побочных эффектах»).
Кеширование и стабы на случай деградации истока.
Graceful Degradation (облегченные ответы, stale-данные, отключение фич).
Timeout-budget (общий бюджет времени по цепочке вызовов).
Атомарность/компенсации (Saga/Outbox/Transactional Inbox).
Кворумы и репликация (R/W кворумы, деградация консистентности ради доступности).
Anti-entropy/реплей (восстановление при «дырах» событий).

6) Рецепты инъекций и ожиданий (псевдокод)

Ретрай с джиттером и брейкером


for attempt in 1..N:
if breaker. open(): return fallback()
res = call(dep, timeout = base 0. 8)
if res. ok: return res sleep(exp_backoff(attempt) jitter(0. 5..1. 5))
if attempt == N: breaker. trip()
return fallback()

Шейдинг и бэкпрешер


if queue. depth() > HIGH          cpu. load() > 0. 85:
if request. priority < HIGH: return 503_SHED limiter. acquire () # constrain concurrency

Идемпотентность


key = hash("payout:"+external_id)
if store. exists(key): return store. get(key)
result = do_side_effect()
store. put(key, result, ttl=30d)
return result

7) Эксперименты: сценарии и гипотезы

7.1 «Медленная зависимость»

Инъекция: +400 мс p95 к внешнему API.
Ожидание: рост таймаутов ≤ X%, открытие брейкера, fallback-ответы, сохранение p99 сервиса < SLA, отсутствие каскада при ретраях.

7.2 «Частичная потеря кэша»

Инъекция: отказ 50% узлов Redis/Кеш-шарда.
Ожидание: увеличенный miss, но без лавины к истоку (request coalescing/иммутабельные TTL), авто-прогрев и восстановление.

7.3 «Split-brain в БД»

Инъекция: потеря лидера, переключение на реплику.
Ожидание: кратковременный deny записей, читаем из кворума, отсутствие потери данных, Outbox не теряет сообщения.

7.4 «ENOSPC/диск заполнен»

Инъекция: диск на 95–100%.
Ожидание: аварийные ротации логов, отказ неблокирующих фич, сохранность критичных журналов (WAL), алерты и автоликвид.

7.5 «Бурст трафика»

Инъекция: ×3 RPS к горячему эндпоинту 10 мин.
Ожидание: шейдинг низкого приоритета, стабильный p95 у «ядерных» путей, рост очередей в пределах лимитов, отсутствие DLQ-штормов.

7.6 «Clock Skew»

Инъекция: смещение времени ноды на +/−2 мин.
Ожидание: корректные TTL/подписи (leeway), монотонические таймеры в ретраях, валидные токены при допустимом дрейфе.

8) Среды и безопасность экспериментов

Начинайте с pre-prod, синтетические данные, максимально близкие к проду конфиги/топология.
В проде — только контролируемые окна, фича-флаги, пошаговая амплитуда, авто-откат, «красная кнопка».
Guardrails: лимиты RPS/ошибок, SLO-охранники, блокировка релизов во время критичных инцидентов.
Обязателен runbook: как откатить, кого позвать, где смотреть.

9) Автоматизация и CI/CD

Каталог экспериментов как код (YAML/DSL): цели, инъекции, метрики, пороги, «кнопки» отката.
Smoke-chaos в каждом релизе: короткие инъекции (например, 2 мин +200 мс к зависимости) в стейдже.
Ночные прогоны матрицы: сервисы × виды отказов.
Гейт на релиз: запрет деплоя, если устойчивость ниже порога (например, `fallback coverage < 95%` под «медленной зависимостью»).

10) Данные и консистентность

Проверяйте компенсации (Saga): частично выполненные операции должны доводиться до согласованного состояния.
Тестируйте повторы/дубли событий, out-of-order доставку, «дыры» и реплей.
Верифицируйте инварианты домена после сбоев: баланс не отрицательный, транзакции не «застревают», лимиты не нарушены.

11) Анти-паттерны

Тестировать только happy-path и нагрузку без отказов.
Ретраи без джиттера → шторм под деградацией.
Отсутствие глобального таймаут-бюджета → каскадные таймауты.
Единый пул для всех задач → отсутствие изоляции (bulkheads).
«Бесконечные» очереди → рост латентности/OOM.
Нулевая телеметрия экспериментов → «слепые» хаос-практики.
Хаос в проде без отката/лимитов/ответственного владельца.

12) Чек-лист архитектора

1. Определена steady-state гипотеза и SLO?
2. На каждом RPC есть таймауты, ретраи с джиттером, брейкеры?
3. Реализованы bulkheads, лимитеры, backpressure, load-shedding?
4. Кэш устойчив: coalescing, защита от кэш-штормов, прогрев?
5. Outbox/Saga для побочных эффектов, идемпотентные ключи?
6. Кворумы/репликация/фейловер протестированы?
7. Есть каталог экспериментов, nightly хаос и гейты в CI/CD?
8. Метрики/трассировки помечают эксперименты, есть дашборды?
9. Runbook’и и «красная кнопка» готовы, ответственность назначена?
10. Регулярные гейм-дей с участием Dev/SRE/Support?

13) Мини-инструменты и примеры сценариев (YAML-скетчи)

Сеть (tc/netem)

yaml experiment: add-latency target: svc:payments inject:
netem:
delay_ms: 300 jitter_ms: 50 loss: 2%
duration: 10m guardrails:
error_rate: "< 1%"
p95_latency: "< 400ms"

CPU/Heap

yaml inject:
cpu_burn: { cores: 2, duration: 5m }
heap_fill: { mb: 512 }

Зависимость

yaml inject:
dependency:
name: currency-api mode: slow p95_add_ms: 500 fallback_expectation: "serve stale rates ≤ 15m old"

Заключение

Тестирование устойчивости — не «трюк с хаосом», а дисциплина, которая делает систему предсказуемой под сбоями. Четкие гипотезы, телеметрия, каталог управляемых экспериментов и встроенные в архитектуру паттерны (таймауты, брейкеры, изоляция, идемпотентность) превращают потенциальные инциденты в контролируемые сценарии. Команда получает уверенность в релизах, а пользователи — стабильный сервис даже в условиях отказов.

Contact

Свяжитесь с нами

Обращайтесь по любым вопросам или за поддержкой.Мы всегда готовы помочь!

Начать интеграцию

Email — обязателен. Telegram или WhatsApp — по желанию.

Ваше имя необязательно
Email необязательно
Тема необязательно
Сообщение необязательно
Telegram необязательно
@
Если укажете Telegram — мы ответим и там, в дополнение к Email.
WhatsApp необязательно
Формат: +код страны и номер (например, +380XXXXXXXXX).

Нажимая кнопку, вы соглашаетесь на обработку данных.