Перейти к содержанию

Failure injection и chaos engineering

Раздел 04 · Типы достоверности

Тип материала: инженерный разбор. Схемы и примеры иллюстративные. Рекомендации — INFERENCE; учебные параметры — HYPOTHETICAL.

Проверка источников: 2026-11-02. Версии и границы первоисточников перечислены в конце. Documented contracts не означают выполненный runtime test.

Принцип работы и границы

Эксперимент задаёт проверяемый инвариант, исходное состояние, fault boundary, наблюдаемые evidence и stop condition. «Процесс перезапустился» — недостаточный результат: нужно проверить effects, identities, offsets и восстановленную полноту.

Principles of Chaos Engineering предлагают проверять гипотезы о steady state при реальных возмущениях. INFERENCE: для денежной цепочки сначала используйте synthetic lab с bounded scope; потерянный ACK, paused old owner и partial publication часто выявляют более опасные ошибки, чем случайный restart всего кластера.

Fault injection должна различать crash до durable commit, после commit и ambiguous transport outcome. Recovery oracle должен быть независимым: expected fixture/cut, ledger invariants, key sets и accounting totals. Тест, который читает только тот же испорченный target, не обнаружит silent loss.

Иллюстративная архитектура

flowchart LR
 H[Hypothesis and invariant] --> F[Controlled fault boundary]
 F --> E[Collect source, state and sink evidence]
 E --> R[Execute recovery runbook]
 R --> O[Independent reconciliation oracle]
 O --> D[Record PASS, FAIL or NOT_RUN]

Failure scenarios

Harness убивает consumer до DB commit, но отчёт заявляет crash после commit. Неполученный ACK трактуется как rollback. Replay использует reused SQLite state и скрывает неправильную первичную обработку. Тест не проверяет corrupted case, поэтому зелёный reconciliation может быть no-op.

Recovery protocol

  1. Для каждого run создать отдельный namespace/workdir и сохранить versions/config/fixture hash.
  2. Дождаться подтверждённой fault boundary по durable evidence; зафиксировать её до injection.
  3. Выполнить fault и recovery, собирая intermediate states, а не только конечный stdout.
  4. Проверить позитивный oracle и deliberately corrupted negative case.
  5. Записать точную область PASS/FAIL; unavailable services — NOT_RUN, model check — MODEL_ONLY. Не превращать успешный harness exit в доказательство всех сценариев.

Trade-offs и критерии выбора

Детерминированные failpoints проще воспроизводить, но они охватывают выбранные interleavings. Реальные process kills и network faults шире, но требуют надёжного orchestration/evidence. Chaos без stop conditions рискует повредить данные и усложняет причинный анализ.

FinTech и iGaming

Для ledger проверяются отсутствие двойного debit и conservation по currency, а для betting analytics — duplicate/correction semantics до merges. Восстановление cache проверяется как completeness, а не только доступность TCP Redis.

Практический пример

Выполните восемь labs. В текущем окружении Docker daemon недоступен; интеграционные fault tests остаются NOT_RUN. Отдельный локальный runner переиспользует старые projection/reconciliation/helpers; его scope и evidence записаны в отчёте Этапа 4.

Типичные ошибки проектирования

Объявлять random restart полным fault coverage; скрывать NOT_RUN; смешивать исторический PASS с новым тестом; тестировать production PII; не записывать исходные offsets/generation.

Вопросы на собеседовании

Что является критерием успеха? Инвариант после recovery с полным evidence, а не только uptime.

Почему нужен negative case? Он подтверждает, что oracle действительно обнаруживает тот класс повреждения, который тест обещает ловить.

Дополнительные источники