Инциденты, продакшен и ответственность за живую систему

О чём этот модуль

Код не заканчивается на merge.

После merge код только получает возможность стать частью живой системы. Он ещё должен быть собран, доставлен, запущен, получить конфигурацию, соединиться с зависимостями, обработать реальные данные, выдержать реальный поток запросов, пережить частичный отказ и сохранить пользовательский сценарий.

merge ≠ delivery
deployment ≠ release
процесс запущен ≠ сервис работает
HTTP 200 ≠ пользователь получил правильный результат
зелёный dashboard ≠ реальность исправна
инцидент завершён ≠ система исправлена

Ответственность лида не заканчивается в точке, где Git принял pull request. Лид удерживает полный контур:

изменение → deployment → реальный трафик → пользовательский сценарий →
наблюдение → обнаружение отклонения → реакция → восстановление →
проверка данных → разбор причин → изменение системы

Продакшен — не место, куда код «уходит» после разработки. Это состояние системы, в котором техническое решение встречается с реальностью.


Результаты обучения

После модуля участник должен уметь:

  • определять, какие пользовательские функции сервиса действительно надо наблюдать;
  • различать telemetry, monitoring и observability;
  • проектировать logging, metrics и tracing как связанную систему сигналов;
  • различать white-box и black-box monitoring;
  • строить alerts по пользовательскому воздействию и срочности действия;
  • отличать page, ticket и информационное уведомление;
  • проектировать устойчивую on-call rotation, escalation path и handover;
  • объявлять инцидент раньше, чем коллективное расследование превратится в хаос;
  • разделять роли Incident Commander, Operations Lead, Communications Lead и Scribe;
  • различать mitigation, recovery, resolution и corrective action;
  • принимать решение между rollback и roll-forward;
  • использовать feature flags, canary и progressive delivery для ограничения blast radius;
  • проводить postmortem без охоты на виноватого и без растворения ответственности;
  • проводить root cause analysis, не останавливаясь на фразе «человек ошибся»;
  • определять SLI, SLO и SLA через пользовательскую функцию;
  • рассчитывать error budget и связывать его с решениями о delivery;
  • проводить operational readiness review до выхода изменения в production;
  • строить систему, которая не зависит от героизма одного человека.

1. Живая система как отдельный объект ответственности

Исходный код и живая система — не один объект.

Исходный код можно прочитать. Живая система существует одновременно в нескольких слоях:

  • исполняющийся код;
  • конфигурация;
  • инфраструктура;
  • состояние данных;
  • очереди и потоки событий;
  • внешние зависимости;
  • реальные пользователи;
  • реальная нагрузка;
  • сетевые задержки и частичные отказы;
  • версии клиентов;
  • процессы deployment и rollback;
  • действия операторов;
  • накопленная история предыдущих изменений.
Один и тот же commit может:
- работать в staging;
- падать только на production data;
- работать в одном регионе и ломаться в другом;
- возвращать 200, но создавать неправильное состояние;
- быть корректным сам по себе, но нарушать старый contract клиента;
- работать при 10 RPS и разрушаться при 1 000 RPS.

Поэтому формула «код прошёл тесты» не завершает рассуждение. Она сообщает только об одном классе наблюдений в одной среде.

Ответственность за production не равна личному всемогуществу

Лид не обязан один чинить базу, Kubernetes, сеть, Kafka, frontend и внешнего провайдера. Его ответственность в другом:

  • границы владения определены;
  • сигналы существуют;
  • alert имеет адресата;
  • эскалация возможна;
  • runbook доступен;
  • изменения обратимы настолько, насколько это возможно;
  • решение о риске принято явно;
  • после сбоя система получает изменение, а не только объяснение.
Ownership — не "я лично делаю всё".

Ownership — "ни одна критическая часть контура
не остаётся без наблюдения, решения и владельца".

2. Пользовательская функция как центр наблюдения

Система существует для выполнения некоторой функции.

Не "у нас CPU нормальный".
А "пользователь может выполнить действие?"

Не "сервер жив".
А "сценарий работает?"

Не "алерт зелёный".
А "сервис выполняет свою функцию?"

Инфраструктурные показатели нужны. CPU, memory, disk, connection pool и consumer lag могут объяснять происходящее и заранее показывать приближение к пределу. Но сами по себе они не определяют здоровье продукта.

Примеры пользовательской функции

Система Пользовательская функция Возможные показатели
Интернет-магазин Покупатель оформляет заказ Доля успешно завершённых checkout, latency, корректность суммы
Платёжный сервис Платёж получает конечный корректный статус Success ratio, time to final state, duplicate charge rate
Поиск Пользователь получает релевантный ответ Availability, latency, empty-result anomalies, correctness proxies
Хранилище Данные можно записать и потом прочитать без потери Write success, read success, durability, consistency
Очередь Принятое сообщение будет обработано в допустимое время Publish success, consumer lag, end-to-end processing latency
Отчётный pipeline Данные появляются полностью и вовремя Freshness, completeness, correctness, processing deadline
Authentication Пользователь получает доступ согласно политике Login success, latency, false denial, false authorization

Google SRE предлагает начинать выбор SLI не с того, что легко измерить, а с того, что важно пользователю. Для user-facing систем типичны availability, latency и throughput; для хранилищ добавляется durability; для data pipelines особенно важны throughput и end-to-end latency. Отдельно подчёркивается correctness: система может быть доступна и быстра, но возвращать неправильный результат. (Google SRE: Service Level Objectives)

Техническое здоровье и функциональное здоровье

Технически зелёно:
- pods Running;
- CPU 35%;
- memory 60%;
- HTTP 2xx = 99.99%.

Функционально сломано:
- событие подтверждения не публикуется;
- заказ остаётся Pending;
- пользователь не получает результат;
- деньги списаны, состояние заказа не изменилось.

Лид должен удерживать оба слоя. Функциональный сигнал обнаруживает воздействие. Технические сигналы помогают локализовать причинность.


3. Telemetry, monitoring и observability

Эти понятия часто используют как синонимы, хотя они обозначают разные слои.

Telemetry

Telemetry — данные, которые система производит о собственном выполнении:

  • logs;
  • metrics;
  • traces;
  • profiles;
  • events.

OpenTelemetry определяет traces как путь запроса через приложение, metrics как измерения во время выполнения, logs как записи событий, а baggage как контекст, передаваемый между сигналами и процессами. (OpenTelemetry Signals)

Monitoring

Monitoring — заранее построенный контур сбора, обработки, визуализации и проверки известных показателей.

Мы заранее решили:
- что измеряем;
- какое состояние считаем нормальным;
- что показываем на dashboard;
- какое отклонение вызывает действие.

Google SRE различает white-box monitoring внутренних показателей системы и black-box monitoring внешнего поведения, видимого пользователю. (Google SRE: Monitoring Distributed Systems)

Observability

Observability в практическом смысле — способность исследовать внутреннее состояние живой системы по производимым ею сигналам, в том числе задавать вопросы, которые не были полностью известны до инцидента.

Monitoring отвечает:
"Нарушено ли заранее известное условие?"

Observability помогает ответить:
"Что именно произошло с этим классом запросов,
в этом регионе, после этого изменения и на этой зависимости?"

Нельзя купить observability установкой одного продукта. Если события не имеют correlation ID, метрики теряют размерности, trace context обрывается, deployment не отмечен на графике, а бизнес-результат не измеряется — дорогой интерфейс не создаст недостающую причинность.

Связанный контур сигналов

Metric:
показывает, что checkout success rate упал.

Trace:
показывает, на каком участке пользовательского пути возникла задержка.

Log:
показывает конкретное решение кода, входной класс и ошибку.

Deployment marker:
показывает, какое изменение совпало с началом отклонения.

Сила возникает не из количества данных, а из возможности переходить между слоями без потери контекста.


4. Logging: журнал решений живой системы

Лог должен позволять восстановить значимое событие и контекст, а не просто подтвердить, что код когда-то прошёл по строке.

Плохой лог

Error processing request

Из него неизвестно:

  • какой запрос;
  • какой пользовательский сценарий;
  • какой компонент;
  • какая стадия;
  • повторяемая ли операция;
  • какое состояние уже изменилось;
  • можно ли безопасно повторить;
  • где искать связанные события.

Структурированный лог

{
  "timestamp": "...",
  "severity": "ERROR",
  "service": "payment-orchestrator",
  "environment": "production",
  "version": "2026.07.21-4f82a1",
  "trace_id": "8ec2...",
  "span_id": "31ad...",
  "request_id": "req-7421",
  "operation": "confirm_payment",
  "provider": "acme-pay",
  "payment_state": "AUTHORIZED",
  "retryable": true,
  "error_code": "PROVIDER_TIMEOUT",
  "duration_ms": 2503,
  "message": "Provider confirmation timed out"
}

Что должно быть в хорошем logging contract

  • единый timestamp и timezone;
  • service, environment и version;
  • severity;
  • operation или event name;
  • request ID / correlation ID / trace ID;
  • безопасные идентификаторы сущностей;
  • итог операции;
  • duration;
  • error category и retryability;
  • ключевое изменение состояния;
  • причина принятого решения, если она важна для расследования.

Log level — не эмоциональная окраска

DEBUG:
детали исследования, обычно отключаемые или sampled.

INFO:
нормальное значимое событие жизненного цикла.

WARN:
отклонение, которое система обработала,
но которое может потребовать анализа.

ERROR:
операция не достигла ожидаемого результата.

FATAL:
процесс или критическая подсистема не может продолжать работу.

Если каждое исключение логируется как ERROR, включая ожидаемую бизнес-валидацию, ERROR перестаёт означать отказ. Если retry пишет одну и ту же ошибку на каждой попытке, один пользовательский сбой превращается в тысячу строк и маскирует масштаб реального воздействия.

Логировать событие, а не шум реализации

Плохо:
"entered method"
"calling repository"
"left method"

Полезнее:
"order state transition rejected:
current=SHIPPED, requested=CANCELLED, policy=immutable_after_shipping"

Безопасность и данные

Нельзя автоматически писать в logs:

  • пароли;
  • access tokens;
  • session cookies;
  • полные номера банковских карт;
  • секреты;
  • чувствительные персональные данные;
  • необработанные request/response bodies без явного основания.

Observability, построенная ценой утечки данных, является новой неисправностью системы.

Retention, sampling и стоимость

Лид должен знать:

  • сколько данных производит сервис;
  • сколько стоит хранение и поиск;
  • какие logs нужны для оперативного расследования;
  • какие нужны для аудита;
  • какие можно sampling;
  • какой retention требуется юридически и технически;
  • что произойдёт с telemetry pipeline при всплеске ошибок.

Если авария увеличивает логирование в сто раз и этим переполняет диск или observability backend, диагностический контур усиливает исходный инцидент.


5. Metrics: видеть состояние системы во времени

Metrics агрегируют поведение системы и позволяют видеть частоту, распределение, изменение и приближение к пределам.

Основные формы

Counter:
монотонно растущее количество событий.
Пример: requests_total, payments_failed_total.

Gauge:
текущее значение, которое может расти и уменьшаться.
Пример: queue_depth, active_connections.

Histogram / distribution:
распределение наблюдений по диапазонам.
Пример: request_duration_seconds.

Four Golden Signals

Google SRE выделяет четыре базовых сигнала для распределённых систем:

  • latency;
  • traffic;
  • errors;
  • saturation.

Они дают стартовую карту, но не заменяют продуктовые SLIs. (Google SRE: Monitoring Distributed Systems)

Latency

Не только среднее время ответа.

p50 — типичный опыт;
p95 — медленный хвост;
p99 — редкий, но массово значимый при большом трафике опыт.

Среднее может оставаться нормальным, когда 1% пользователей ждёт в двадцать раз дольше. Google SRE поэтому рекомендует рассматривать latency как распределение и использовать percentiles, а не полагаться только на mean. (Google SRE: Service Level Objectives)

Надо также разделять:

  • успешные и неуспешные запросы;
  • server latency и client-observed latency;
  • отдельные классы операций;
  • end-to-end latency и время отдельного сервиса.

Быстрый 500 не является хорошей latency.

Traffic

Traffic — реальный спрос на систему:

  • requests per second;
  • active users;
  • messages per second;
  • объём данных;
  • concurrent sessions;
  • jobs per interval.

Без traffic нельзя интерпретировать другие метрики. Пять ошибок при десяти запросах и пять ошибок при десяти миллионах — разные состояния.

Errors

Ошибки должны отражать не только технический exception.

Техническая ошибка:
HTTP 500, timeout, rejected message.

Функциональная ошибка:
HTTP 200, но заказ не создан.

Ошибочный результат:
отчёт сформирован, но сумма неверна.

Нарушение времени:
задача завершилась корректно, но после бизнес-deadline.

Saturation

Saturation показывает, насколько система приблизилась к пределу:

  • CPU throttling;
  • memory pressure;
  • queue depth;
  • connection pool utilization;
  • thread pool queue;
  • disk I/O;
  • consumer lag;
  • rate-limit utilization.

CPU 90% сам по себе не всегда инцидент. Но рост queue depth при исчерпанном connection pool и ухудшении пользовательской latency уже образует причинную картину.

Cardinality

Labels делают метрику полезной, но каждый новый набор значений создаёт отдельный time series.

Хорошие labels:
region, operation, status_class, provider.

Опасные labels:
user_id, request_id, raw_url, order_id.

Высокая cardinality способна разрушить стоимость и производительность monitoring backend. Конкретный request ID обычно принадлежит logs и traces, а не metrics.


6. Tracing: причинный путь запроса

В распределённой системе один пользовательский сценарий проходит через несколько процессов, сервисов, очередей и хранилищ.

Trace связывает этот путь.

Trace
└── frontend request
    ├── authentication
    ├── order service
    │   ├── database query
    │   └── inventory reservation
    └── payment authorization

Основные элементы

Trace:
весь причинный путь операции.

Span:
одна операция или участок работы.

Parent / child relation:
связь этапов.

Attributes:
структурированный контекст.

Events:
значимые события внутри span.

Status:
итог операции.

OpenTelemetry описывает trace как end-to-end представление, которое может объединять spans из разных процессов, сервисов, виртуальных машин и дата-центров. (OpenTelemetry Traces)

Где tracing особенно полезен

  • fan-out на множество зависимостей;
  • длинные цепочки microservices;
  • различие server time и waiting time;
  • поиск источника tail latency;
  • асинхронная обработка;
  • повторные попытки;
  • cross-region запросы;
  • сравнение старого и нового пути под feature flag.

Context propagation

Trace context должен пересекать:

  • HTTP/gRPC boundaries;
  • message broker;
  • background jobs;
  • scheduler;
  • async callbacks.

Если correlation обрывается в Kafka, trace показывает только отправку сообщения, но не продолжение пользовательского действия.

Sampling

Хранить 100% traces не всегда возможно. Но слепой случайный sampling может выбросить именно редкие ошибки и медленный хвост.

Возможные стратегии:

  • head sampling — решение принимается в начале trace;
  • tail sampling — решение принимается после появления результата;
  • повышенная выборка ошибок;
  • повышенная выборка медленных запросов;
  • отдельные правила для критических операций.

Sampling policy должна быть частью архитектуры наблюдаемости, а не случайной настройкой агента.

Baggage и риск

Baggage переносит контекст между процессами, но не должен превращаться в канал бесконтрольного распространения персональных данных и секретов. Передаваемый атрибут размножается по цепочке и может попасть в разные telemetry backends.


7. Correlation: соединение signals и изменений

Logs, metrics и traces не должны существовать тремя изолированными складами.

Минимальный correlation contract

  • service.name;
  • service.version;
  • deployment.environment;
  • region / zone;
  • trace_id и span_id в logs;
  • operation name;
  • feature flag variant;
  • deployment marker;
  • безопасный business entity reference;
  • единая временная шкала.

Почему версия обязательна

Наблюдение:
error rate вырос в 14:03.

Без version:
мы начинаем гадать, связано ли это с release.

С version:
ошибки концентрируются на 2026.07.21-4f82a1,
а предыдущая версия остаётся стабильной.

Feature flag как измеряемая размерность

Если новая логика включена для 10% пользователей, telemetry должна позволять сравнить control и treatment.

checkout_success_rate{flag_variant="old"}
checkout_success_rate{flag_variant="new"}

Но нельзя механически добавлять идентификатор каждого флага в каждую метрику: это создаёт cardinality explosion. Нужен ограниченный набор значимых экспериментальных размерностей.


8. Health checks: жив, готов и реально работает — разные состояния

В container orchestration часто используются liveness, readiness и startup probes.

Startup:
успело ли приложение завершить запуск.

Liveness:
способно ли оно продолжать выполнение,
или процесс надо перезапустить.

Readiness:
можно ли сейчас направлять на instance пользовательский трафик.

Kubernetes использует readiness, чтобы определять, должен ли Pod получать трафик, liveness — чтобы решать вопрос о перезапуске, а startup probe — чтобы не применять остальные проверки до завершения медленного запуска. (Kubernetes Probes)

Антипаттерн: одна проверка на всё

Если liveness проверяет доступность внешней базы, краткий сбой базы может заставить все instances одновременно перезапуститься. Исходная зависимость восстановится, но приложение само создаст вторую волну отказа.

Антипаттерн: всегда возвращать 200

/health → 200 "OK"

потому что web server отвечает, ничего не говорит о пользовательском сценарии.

Но и глубокая проверка не решает всё

Health endpoint, который синхронно вызывает все зависимости, может:

  • создавать дополнительную нагрузку;
  • усиливать cascade;
  • становиться медленным;
  • показывать service unhealthy из-за необязательной функции;
  • вызывать одновременное удаление всех instances из traffic.

Нужны разные проверки для разных решений:

  • процесс перезапустить;
  • instance вывести из traffic;
  • сервис объявить degraded;
  • пользователя предупредить;
  • человека вызвать.

9. Dashboards: карта принятия решений

Dashboard — не стена графиков.

Хороший dashboard помогает за несколько минут ответить:

Пользователи затронуты?
Какой сценарий нарушен?
Когда началось?
Каков масштаб?
В каких регионах, версиях и сегментах?
Что изменилось рядом по времени?
Где находится возможное ограничение?
Сжигается ли error budget?

Service overview dashboard

Первый экран:

  • текущий SLO status;
  • error budget remaining;
  • request / transaction volume;
  • success ratio;
  • latency percentiles;
  • saturation;
  • active incidents;
  • current deployments;
  • current on-call;
  • ссылки на runbooks.

User journey dashboard

Например, checkout:

cart_opened
→ checkout_started
→ payment_authorized
→ inventory_reserved
→ order_confirmed
→ confirmation_delivered

Если каждый сервис по отдельности зелёный, а переход payment_authorized → order_confirmed провалился, journey dashboard обнаруживает разрыв смысла между локальными компонентами.

Dashboard не должен требовать постоянного наблюдателя

Если система безопасна только пока кто-то смотрит на экран, alerting не построен. Google SRE отдельно отмечает, что мониторинг не должен зависеть от человека, который непрерывно «смотрит на графики». (Google SRE: Monitoring Distributed Systems)


10. Alerts: когда система имеет право прервать человека

Metric сообщает значение. Alert сообщает: нужно человеческое действие.

Полезный alert отвечает на вопросы

Что нарушено?
Кого затрагивает?
Насколько срочно?
Какой ожидается первый шаг?
Кто владелец?
Где dashboard и runbook?
Что изменилось недавно?

Page, ticket и notification

Канал Условие Ожидаемое действие
Page Пользовательское воздействие идёт сейчас или скоро станет существенным Человек прерывает текущую деятельность немедленно
Ticket Проблема требует исправления, но может ждать рабочего времени Владелец планирует и выполняет работу
Notification Информация полезна для контекста, но действия не требуется Получатель может ознакомиться

Если alert не требует действия, он не должен маскироваться под page.

Symptom-based alerting

Будить человека лучше по наблюдаемому воздействию:

Плохо:
CPU > 80%.

Лучше:
checkout success rate нарушает SLO,
а error budget сгорает с высокой скоростью.

CPU может оставаться диагностическим сигналом на dashboard или предупреждением capacity planning. Но page оправдан, если человеку надо действовать сейчас.

Google SRE подчёркивает высокую стоимость page: он прерывает работу, личное время и сон, а частый шум приводит к тому, что люди начинают пропускать реальные сигналы. Эффективная alerting system должна иметь сильный signal и низкий noise. (Google SRE: Monitoring Distributed Systems)

Cause-based alerting

Alert по причине оправдан, когда:

  • причина надёжно предсказывает скорое пользовательское воздействие;
  • ждать нарушения уже поздно;
  • действие однозначно;
  • false positive достаточно редки.

Пример: осталось слишком мало места для append-only log, а достижение нуля приведёт к потере записи раньше, чем пользовательский SLI успеет сработать.

Alert fatigue

Признаки:

  • pages регулярно не требуют действий;
  • alert автоматически закрывается до реакции;
  • on-call знает, какие alerts можно игнорировать;
  • один инцидент создаёт сотни уведомлений;
  • alerts не имеют владельцев;
  • threshold повышают после каждого ложного срабатывания;
  • невозможно определить, какой alert был первичным.

Лид должен рассматривать pager load как дефект системы, а не как доказательство её серьёзности.

Alert review

Для каждого page периодически проверяется:

Было ли пользовательское воздействие?
Требовалось ли срочное действие?
Помог ли alert начать правильное расследование?
Был ли runbook актуален?
Можно ли автоматизировать действие?
Нужно ли изменить threshold, окно или сам SLI?

11. SLI, SLO и SLA

SLI — Service Level Indicator

SLI — количественный показатель реально предоставленного уровня сервиса.

Google SRE определяет SLI как тщательно заданную количественную меру некоторого аспекта service level. (Google SRE: Service Level Objectives)

Часто удобно выражать SLI как долю хороших событий:

SLI = good events / valid events

Примеры:

Availability SLI:
успешные валидные запросы / все валидные запросы.

Latency SLI:
запросы быстрее 300 ms / все валидные запросы.

Freshness SLI:
отчёты, опубликованные до 08:00 / все ожидаемые отчёты.

Correctness SLI:
заказы с правильной итоговой суммой / все завершённые заказы.

Что такое valid event

Границы знаменателя нельзя выбирать ради красивого результата.

Можно исключить заведомо некорректный пользовательский запрос, если сервис и не обещал его выполнить. Но нельзя исключить timeout, потому что «это проблема зависимости», если для пользователя операция всё равно не выполнена.

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

SLO — Service Level Objective

SLO — целевое значение или диапазон для SLI.

За rolling window 28 дней:

99.9% валидных checkout attempts
завершаются созданием корректного заказа
не более чем за 2 секунды.

Полный SLO содержит:

  • service boundary;
  • пользователя или класс трафика;
  • событие;
  • критерий good;
  • критерий valid;
  • target;
  • measurement window;
  • источник измерения;
  • обработку missing data;
  • владельца;
  • error budget policy.

SLA — Service Level Agreement

SLA — договорённость, содержащая последствия нарушения уровня сервиса.

Последствия могут быть:

  • финансовая компенсация;
  • service credits;
  • право расторгнуть договор;
  • регуляторная ответственность;
  • иная формальная обязанность.

Google SRE предлагает простой тест: если при нарушении нет явных последствий, скорее всего, речь идёт об SLO, а не об SLA. SLA находится не только в техническом, но и в продуктовом, коммерческом и юридическом контуре. (Google SRE: Service Level Objectives)

Сводное различение

SLI:
что реально измерили.

SLO:
какой уровень считаем целевым.

SLA:
о каком уровне договорились и что произойдёт при нарушении.

Почему 100% — плохой автоматический target

100% availability обычно означает:

  • запрет разумного изменения;
  • огромную стоимость;
  • скрытие ошибок из знаменателя;
  • фиктивную отчётность;
  • систему, которая всё равно не может контролировать каждую зависимость.

Надёжность — продуктовая характеристика с ценой. Её уровень выбирается на основании пользовательской необходимости и стоимости отказа, а не по принципу «больше девяток всегда лучше».


12. Error budget: допустимая граница ненадёжности

Если SLO равен 99.9%, error budget равен 0.1%.

Error budget = 1 − SLO

Для request-based SLO:

10 000 000 валидных запросов за окно.
SLO = 99.9%.

Error budget = 10 000 плохих запросов.

Для time-based availability за 28 дней:

28 × 24 × 60 = 40 320 минут.
0.1% = 40.32 минуты.

Error budget не является целью потратить ошибки

Это граница риска, а не квота на обязательный outage.

Он отвечает на вопрос:

Сколько ненадёжности продукт может допустить,
прежде чем скорость изменений должна уступить восстановлению стабильности?

Error budget policy

Политика заранее определяет:

  • кто смотрит на budget;
  • когда требуется действие;
  • какие изменения ограничиваются;
  • какие reliability work получают приоритет;
  • какие исключения допустимы;
  • кто разрешает спор;
  • когда policy пересматривается.

Google SRE подчёркивает, что error budget policy должна быть согласована product, development и SRE/operations. Исчерпание бюджета не является наказанием; оно даёт основание временно поставить reliability выше нового feature delivery. (Google SRE Workbook: Implementing SLOs)

Burn rate

Burn rate показывает, во сколько раз быстрее допустимого расходуется error budget.

Burn rate = 1:
при сохранении текущего уровня budget закончится ровно к концу окна.

Burn rate = 10:
budget расходуется в десять раз быстрее допустимого.

При SLO 99.9% на 30 дней burn rate 10 означает error rate 1% и исчерпание бюджета примерно за три дня. Google SRE Workbook использует burn rate для alerting, потому что он связывает масштаб ошибки, длительность и реальное потребление бюджета. (Google SRE Workbook: Alerting on SLOs)

Multi-window alerting

Короткое окно быстро видит резкий outage, но может шуметь. Длинное окно подтверждает устойчивое потребление budget, но реагирует медленнее.

Комбинация окон позволяет отличить:

  • короткий катастрофический сбой;
  • медленную хроническую деградацию;
  • случайный spike без существенного воздействия.

Error budget как язык приоритета

Без budget:
Product: "Нужны features".
Engineering: "Нужна стабильность".

С budget:
"За восемь дней потрачено 70% месячного бюджета.
Основной класс потерь — timeout нового payment path.
До восстановления burn rate мы не расширяем rollout
и выполняем action items A и B".

Метрика не принимает решение вместо людей. Она создаёт общую реальность для решения.


13. On-call: право системы вызвать человека

On-call — это не список телефонов и не наказание за владение сервисом. Это специально спроектированный operational capability.

Что должно существовать до on-call

  • определённая service ownership;
  • расписание primary и secondary;
  • работающий paging channel;
  • escalation path;
  • production access;
  • безопасный break-glass process;
  • dashboards;
  • runbooks;
  • известные rollback и mitigation actions;
  • правила объявления incident;
  • handover;
  • обучение и shadow shifts;
  • время после тяжёлого ночного вызова;
  • регулярный анализ pager load.

Google SRE называет ясные escalation paths, определённые incident-management procedures и blameless postmortem culture основными ресурсами устойчивого on-call. (Google SRE: Being On-Call)

Primary и secondary

Primary:
принимает page и начинает реакцию.

Secondary:
подхватывает параллельную диагностику,
эскалацию или заменяет primary при недоступности.

Роли должны быть реальными. Secondary, который не получает контекст и не умеет войти в production, существует только в расписании.

Handover

Передача смены включает:

  • открытые incidents;
  • текущие degradations;
  • опасные deployments;
  • временно отключённые alerts;
  • известные capacity risks;
  • незавершённые migrations;
  • feature flags в нестандартном состоянии;
  • ожидаемые внешние события.

On-call без полномочий

Человек не может отвечать за восстановление, если он:

  • не имеет доступа;
  • не может остановить rollout;
  • не имеет права переключить traffic;
  • не может вызвать владельца зависимости;
  • боится объявить incident;
  • должен ждать менеджера для любого mitigation.
Ответственность без полномочий
не создаёт ownership.

Она создаёт назначенного свидетеля аварии.

Устойчивость rotation

Если alerts систематически ломают сон, проблема не решается призывом «быть ответственнее».

Нужно менять:

  • alert quality;
  • число людей;
  • follow-the-sun coverage;
  • automation;
  • стабильность сервиса;
  • границы ownership;
  • уровень operational toil.

Человеческая способность реагировать является частью capacity системы.


14. Что такое incident

Incident — незапланированное состояние, которое уже нарушает или существенно угрожает нарушить ожидаемую функцию сервиса и требует координированной реакции.

Не каждый bug — incident. Не каждый alert — incident. И incident может существовать до того, как root cause известен.

Основания объявить incident

  • нарушен критический пользовательский сценарий;
  • быстро расходуется error budget;
  • существует риск потери или повреждения данных;
  • нарушена безопасность;
  • затронут значимый сегмент пользователей;
  • несколько команд уже расследуют одну проблему;
  • причина неясна, а воздействие растёт;
  • требуется координация изменений и коммуникации;
  • отдельный инженер больше не способен удерживать контур один.

Объявить рано дешевле, чем поздно

Formal incident mode можно отменить. Потерянное в неструктурированном хаосе время вернуть нельзя.

Google SRE Workbook приводит случаи, где позднее объявление incident приводило к несогласованной реакции и более долгому восстановлению. (Google SRE Workbook: Incident Response)

Пример severity model

Названия уровней организация определяет сама, но критерии должны опираться на impact.

Severity Пример воздействия Режим
SEV-0 Угроза безопасности людей, критическая потеря данных, полный системный кризис Немедленная максимальная эскалация и executive coordination
SEV-1 Критический сценарий массово недоступен, существенный финансовый или договорный риск Incident command, page всех нужных владельцев, регулярные updates
SEV-2 Частичная деградация, значимый сегмент затронут, workaround ограничен Координированная реакция и контролируемая коммуникация
SEV-3 Ограниченное воздействие, устойчивый workaround, нет быстрого роста Владелец, ticket, исправление в рабочем режиме

Severity может повышаться и понижаться по мере появления фактов.


15. Incident response: сначала вернуть функцию

Главная цель активного incident response — ограничить воздействие и восстановить функцию. Не доказать интеллектуальное превосходство расследования.

Фазы

1. Detect
увидеть отклонение.

2. Triage
проверить воздействие и масштаб.

3. Declare
явно включить incident mode.

4. Contain / Mitigate
остановить рост воздействия и вернуть функцию.

5. Recover
восстановить нормальное обслуживание.

6. Validate
проверить сценарии, данные и хвосты очередей.

7. Resolve
зафиксировать стабильное состояние и закрыть активную фазу.

8. Learn
провести postmortem и изменить систему.

Mitigation, recovery, resolution и corrective action

Mitigation:
уменьшили воздействие.
Например, отключили новый payment path.

Recovery:
пользовательская функция восстановлена.
Например, checkout снова проходит через старого провайдера.

Resolution:
непосредственная неисправность устранена,
состояние стабильно и проверено.

Corrective action:
система изменена так, чтобы снизить вероятность
или воздействие повторения этого класса отказа.

Снова зелёный график не означает, что исправлены данные, разобрана очередь, уведомлены пользователи и устранены условия повторения.

Mitigate before root cause

Если rollback безопасен и возвращает функцию, не надо сначала доказывать root cause.

Плохая последовательность:
"Сначала полностью поймём, почему новая версия ломается,
потом решим, откатывать ли".

Нормальная последовательность:
"Новая версия коррелирует с impact.
Rollback имеет низкий дополнительный риск.
Откатываем, параллельно сохраняем данные для расследования".

Root cause analysis важен после стабилизации. Во время активного воздействия приоритетом является пользовательская функция.


16. Роли внутри incident response

Когда участников становится много, отсутствие структуры начинает производить дополнительный сбой.

Incident Commander

IC удерживает общую картину и процесс:

  • объявляет severity;
  • определяет цели текущей фазы;
  • назначает роли;
  • выбирает между competing actions;
  • следит за риском действий;
  • запрашивает эскалацию;
  • определяет cadence updates;
  • принимает решение о завершении incident mode.

IC не обязан быть самым глубоким экспертом по сломанному компоненту. Если он одновременно погружается в каждую команду и пишет fix, координация остаётся без владельца.

Operations Lead

OL управляет техническим восстановлением:

  • формирует hypotheses;
  • распределяет investigation streams;
  • проводит mitigation;
  • проверяет результат;
  • контролирует изменения в production;
  • не допускает конфликтующих действий.

Communications Lead

CL удерживает информационный контур:

  • внутренние status updates;
  • stakeholders;
  • support;
  • status page;
  • сообщения клиентам;
  • фиксация того, что известно и неизвестно;
  • защита responders от повторяющихся запросов.

Scribe

Scribe ведёт временную шкалу:

  • симптомы;
  • решения;
  • выполненные действия;
  • результаты;
  • hypotheses;
  • владельцев;
  • изменения severity;
  • время updates.

Google SRE описывает структуру с Incident Commander, Operations Lead и Communications Lead; формальное распределение ролей особенно важно, когда incident пересекает команды и коммуникация сама становится ограничением. (Google SRE Workbook: Incident Response)

Decision log

14:07 — rollout остановлен на 25%.
Основание: success rate treatment-группы ниже control на 18%.
Owner: OL.

14:11 — принято решение выключить flag.
Риск: часть сообщений уже записана в новом формате.
Mitigation: включить compatibility consumer перед выключением.

Такой журнал нужен не для последующего наказания. Он сохраняет причинность в момент, когда память людей перегружена.


17. Коммуникация во время incident

Молчание не уменьшает воздействие. Но поток непроверенных версий тоже разрушает управление.

Status update

Incident: INC-2026-042
Severity: SEV-1

Impact:
около 32% checkout attempts остаются в Pending
после успешной авторизации платежа.

Started:
13:54.

Current state:
новый payment path отключён для нового трафика.
Старый path работает. Обрабатываем уже созданные Pending orders.

Known:
ошибка связана с публикацией confirmation event
в новой версии producer configuration.

Unknown:
полный объём заказов, требующих reconciliation.

Next actions:
- восстановить события из outbox;
- сверить платежи и заказы;
- подтвердить пользовательский recovery.

Next update:
через 20 минут или при существенном изменении.

Факт, гипотеза и решение

Факт:
consumer lag вырос после deployment.

Гипотеза:
новая serialization config создаёт rejected messages.

Решение:
остановить rollout и переключить producer на прошлую config.

Если гипотеза формулируется как факт, команда слишком рано замыкается на одной версии.

Cadence

Update должен выходить регулярно, даже если root cause ещё не найден.

Нормальный update:
"Воздействие сохраняется. Новых подтверждённых причин нет.
Проверили database saturation — не подтверждено.
Сейчас исследуем producer rejects. Следующий update через 20 минут".

Неизвестность можно сообщать точно. Для этого не надо выдумывать уверенность.


18. Rollback и roll-forward

Rollback

Возврат к предыдущей версии или конфигурации.

Подходит, если:

  • impact начался после изменения;
  • предыдущая версия совместима с текущими данными;
  • откат автоматизирован и проверен;
  • причина ещё не ясна, но корреляция сильна;
  • продолжение rollout увеличивает blast radius.

Roll-forward

Исправление новой версией.

Подходит, если:

  • rollback опаснее;
  • данные уже мигрированы необратимо;
  • fix локален и хорошо понятен;
  • предыдущая версия содержит другую критическую проблему;
  • clients уже зависят от нового contract;
  • откат займёт дольше безопасного patch.

Решение не должно быть религиозным

Вопросы:
- какой вариант быстрее уменьшит impact;
- какой вариант лучше известен;
- совместимы ли данные;
- можно ли ограничить traffic;
- что произойдёт с in-flight operations;
- есть ли сохранённый rollback artifact;
- проверялся ли rollback вообще;
- можно ли сначала выключить feature flag.

Database migrations

Откат приложения часто ломается из-за схемы данных.

Полезен expand/contract подход:

1. Expand:
добавить новую структуру, сохранив совместимость со старым кодом.

2. Migrate:
перенести или дублировать данные.

3. Switch:
перевести чтение и запись на новую структуру.

4. Contract:
удалить старую структуру только после безопасного окна.

Rollback должен проектироваться до deployment. Во время incident уже поздно обнаруживать, что предыдущий binary не умеет читать новую запись.

Проверка rollback

"Pipeline умеет выполнить команду rollback"

не равно:

"Система после rollback возвращает пользовательскую функцию
и сохраняет корректность уже изменённых данных".

19. Feature flags и progressive delivery

Feature flag отделяет deployment кода от release поведения.

OpenFeature определяет feature flag как управляемое во время выполнения условие, позволяющее изменять поведение приложения без нового deployment. (OpenFeature)

Что дают flags

  • постепенное включение;
  • внутреннее тестирование в production;
  • включение по сегментам;
  • canary;
  • A/B experiment;
  • kill switch;
  • быстрый возврат на старый path;
  • отдельное управление рискованной зависимостью.

Deployment и release

Deployment:
код физически оказался в production.

Release:
новое поведение стало доступно пользователям.

Это различение уменьшает blast radius, если telemetry позволяет сравнивать старый и новый path.

Lifecycle флага

Каждый flag должен иметь:

  • имя и назначение;
  • owner;
  • default value;
  • безопасное поведение при недоступности flag provider;
  • аудит изменений;
  • дату или условие удаления;
  • dashboard;
  • rollout plan;
  • rollback condition.

Feature flag debt

Старый flag создаёт дополнительные состояния системы.

3 независимых boolean flags
→ до 8 комбинаций поведения.

10 flags
→ до 1 024 комбинаций.

Не все комбинации достижимы, но каждая забытая ветка увеличивает пространство проверки и расследования.

Kill switch должен быть проверен

Нельзя считать flag rollback mechanism, если:

  • изменение применяется с задержкой;
  • SDK требует недоступный control plane;
  • default включает опасный path;
  • старый path больше не совместим с данными;
  • никто не имеет права изменить flag;
  • изменение не оставляет audit trail.

Progressive rollout

internal users
→ 1%
→ 5%
→ 25%
→ 50%
→ 100%

Переход между этапами должен зависеть от наблюдаемых критериев:

  • SLI treatment не хуже control;
  • error budget burn rate допустим;
  • нет data integrity violations;
  • saturation остаётся в пределах;
  • support signals не показывают новый класс проблем.

Google SRE рассматривает canary как способ ограничить долю error budget, которой рискует новый release: риск ограничивается временем и размером canary population. (Google SRE Workbook: Canarying Releases)


20. Graceful degradation и ограничение blast radius

Надёжность — не только способность не падать. Это способность сохранять наиболее важную функцию при частичном отказе.

Graceful degradation

Recommendation service недоступен:
показываем популярные товары.

Image processing перегружен:
возвращаем исходное изображение меньшего качества.

Analytics pipeline отстаёт:
checkout продолжает работать,
analytics обрабатывается позже.

Bulkheads

Разделение ресурсов не позволяет одному классу нагрузки уничтожить весь сервис:

  • отдельные thread pools;
  • отдельные queues;
  • отдельные rate limits;
  • tenant isolation;
  • региональные границы;
  • разные failure domains.

Circuit breaker

Если зависимость массово отказывает, бесконечные повторные запросы увеличивают её перегрузку и исчерпывают ресурсы вызывающего сервиса.

Circuit breaker временно прекращает вызовы и даёт системе контролируемо деградировать.

Retry budget

Retry не является бесплатным восстановлением.

1 исходный запрос × 3 уровня × 3 retries
может превратиться в лавину повторов.

Нужны:

  • timeout;
  • ограниченное число retries;
  • exponential backoff;
  • jitter;
  • idempotency;
  • общий retry budget;
  • понимание, какие ошибки retryable.

Load shedding

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

Лид должен знать, какая функция является ядром, а что можно временно отключить.


21. Postmortem: восстановить причинность после сбоя

Postmortem — не отчёт ради закрытия incident ticket. Это механизм преобразования пережитого сбоя в изменение системы.

Когда нужен postmortem

Критерии задаются заранее:

  • превышен severity threshold;
  • существенно потрачен error budget;
  • была потеря или повреждение данных;
  • затронута безопасность;
  • recovery занял слишком долго;
  • incident мог стать значительно хуже;
  • повторился известный класс отказа;
  • обнаружен системный пробел, важный для других команд.

Структура

1. Summary
что произошло.

2. Impact
кого, как и сколько времени затронуло.

3. Detection
как обнаружили и почему не раньше.

4. Timeline
факты, решения и действия.

5. Technical narrative
как развивался отказ.

6. Contributing factors
какие условия сделали incident возможным или усилили его.

7. What went well
что ограничило воздействие.

8. What went poorly
что задержало detection, mitigation или recovery.

9. Where we got lucky
что могло ухудшить incident, но случайно не ухудшило.

10. Action items
какие изменения, владельцы, приоритеты и критерии проверки.

Impact должен быть пользовательским

Плохо:
"Kafka consumer был недоступен 47 минут".

Нормально:
"В течение 47 минут 18 420 оплаченных заказов
не получили подтверждение; 3 120 пользователей повторили попытку,
для 84 платежей потребовалась ручная reconciliation".

Timeline — не художественный рассказ

Нужны:

  • время;
  • наблюдение;
  • решение;
  • действие;
  • результат.

Если время приблизительное, это указывается. Реконструкция не должна выдаваться за наблюдение.

Action items

Хороший action item:

"Добавить contract test, который запускает payment event
через production-equivalent Kafka configuration
и проверяет чтение текущим consumer.
Owner: Payments Platform.
Priority: P1.
Validation: test падает на конфигурации из incident".

Плохой action item:

"Быть внимательнее при изменении Kafka".

22. Blameless culture без превращения в безответственность

Blameless означает: расследование не останавливается на моральном приговоре человеку.

Google SRE описывает blameless postmortem как исследование системных условий, при которых человек располагал неполной или неверной информацией, а совершённое действие выглядело допустимым. Цель — построить предотвращение, а не выпустить раздражение через назначение виновного. (Google SRE: Postmortem Culture)

Blameless не означает

  • никто ни за что не отвечает;
  • решения нельзя критиковать;
  • нарушение процедуры надо скрыть;
  • action items необязательны;
  • любой риск допустим;
  • повторение одного и того же игнорируется;
  • умышленное действие приравнивается к добросовестной ошибке.

Ответственность сохраняется

Человек отвечает за:

  • точное описание своего действия;
  • передачу известного контекста;
  • участие в разборе;
  • выполнение взятого action item;
  • изменение практики после появления нового знания.

Лид отвечает за:

  • отсутствие карательного спектакля;
  • полноту причинного анализа;
  • приоритизацию corrective actions;
  • устранение организационных условий;
  • проверку, что выводы стали изменением системы.

Где проходит граница

Добросовестная ошибка, решение при неполной информации, сознательное принятие согласованного риска, систематическое пренебрежение и умышленное нарушение — разные классы событий.

Blameless culture не обязана стирать это различие. Она запрещает использовать слово «виноват» как замену анализа.

"Инженер запустил скрипт"
не отвечает на вопросы:

- почему destructive mode был default;
- почему production и staging выглядели одинаково;
- почему не было dry-run;
- почему доступ позволял массовое действие;
- почему не потребовалось подтверждение scope;
- почему backup нельзя было быстро восстановить;
- почему alert пришёл после пользовательских жалоб.

23. Root Cause Analysis: не искать одну магическую причину

Сложный incident редко имеет одну линейную причину.

Полезнее различать:

Trigger:
что непосредственно запустило событие.

Latent condition:
какая уязвимость уже существовала.

Contributing factors:
что увеличило вероятность или масштаб.

Propagation mechanism:
почему локальный отказ распространился.

Detection gap:
почему система не показала проблему раньше.

Response gap:
что задержало mitigation.

Recovery factor:
что помогло восстановиться.

Пример

Trigger:
deployment новой producer configuration.

Latent condition:
staging использовал другой security protocol.

Contributing factors:
- config schema не проверяла обязательное поле;
- canary смотрел только HTTP success;
- asynchronous confirmation не входил в release gate.

Propagation:
повторы увеличили очередь rejected messages.

Detection gap:
не было SLI по time-to-final-order-state.

Response gap:
runbook не описывал отключение нового path.

Human error — начало вопроса

"Инженер указал неправильный параметр"

может быть фактом. Но RCA начинается дальше:

  • почему параметр принимал опасное значение;
  • почему система его не проверила;
  • почему review не имел нужного контекста;
  • почему canary не видел эффект;
  • почему blast radius был большим;
  • почему recovery зависел от ручного действия.

5 Whys

Метод полезен как способ продолжать вопрос, но опасен, если заставляет многопричинную систему выглядеть одной цепочкой.

Лучше строить несколько ветвей:

  • change path;
  • data path;
  • detection path;
  • response path;
  • organizational path.

Correlation не равна causation

Последний deployment — сильный кандидат, но не автоматическая причина. Одновременно могли измениться traffic, feature flag, certificate, dependency или data distribution.

Нужно сохранять возможность rollback для mitigation, не превращая временную корреляцию в окончательный вывод postmortem.


24. Operational readiness

Operational readiness — доказательство того, что систему можно не только запустить, но и безопасно эксплуатировать.

Google SRE использует Production Readiness Review для оценки архитектуры, зависимостей, instrumentation, monitoring, emergency response, capacity, change management и performance до принятия production responsibility. (Google SRE: Production Readiness Review)

24.1. Ownership

[ ] Определён service owner.
[ ] Определены owners зависимостей.
[ ] Есть primary и secondary on-call.
[ ] Известен escalation path.
[ ] Есть доступы и break-glass procedure.

24.2. Service contract

[ ] Определены пользователи и критические journeys.
[ ] Определены SLI и SLO.
[ ] Ясно, что считается degraded и unavailable.
[ ] Определены классы трафика.
[ ] Зафиксированы ограничения и unsupported scenarios.

24.3. Architecture and dependencies

[ ] Есть актуальная architecture overview.
[ ] Известны hard и soft dependencies.
[ ] Определено поведение при отказе каждой критической зависимости.
[ ] Настроены timeouts, retries, circuit breakers и rate limits.
[ ] Ограничен blast radius.

24.4. Capacity

[ ] Проведён load test или есть другое основание capacity model.
[ ] Известен saturation point.
[ ] Настроено scaling behavior.
[ ] Учтён launch spike.
[ ] Есть graceful degradation / load shedding.

24.5. Data

[ ] Определены backup и restore.
[ ] Restore реально проверен.
[ ] Миграции backward-compatible или имеют явный plan.
[ ] Есть reconciliation для критических состояний.
[ ] Определены RPO и RTO, если применимо.
[ ] Проверены retention и data privacy.

24.6. Observability

[ ] Logs структурированы и не содержат секретов.
[ ] Metrics отражают user journeys.
[ ] Trace context проходит критический path.
[ ] На telemetry есть version и environment.
[ ] Есть service overview dashboard.
[ ] Есть SLO / error budget dashboard.
[ ] Deployment и flag changes отмечаются.

24.7. Alerting and on-call

[ ] Каждый page требует срочного действия.
[ ] У alert есть owner, runbook и dashboard.
[ ] Alerts проверены тестовым срабатыванием.
[ ] Есть symptom-based alerts.
[ ] Pager load приемлем.
[ ] On-call умеет выполнить mitigation.

24.8. Delivery safety

[ ] Есть canary или staged rollout.
[ ] Определены release gates.
[ ] Rollback автоматизирован и проверен.
[ ] Feature flags имеют owners и safe defaults.
[ ] Есть freeze / stop mechanism.
[ ] In-flight operations корректно переживают переключение.

24.9. Incident response

[ ] Определены severity levels.
[ ] Есть incident channel и state document template.
[ ] Известны IC / OL / CL roles.
[ ] Есть internal и external communication paths.
[ ] Проведена incident simulation или game day.

24.10. Runbooks

[ ] Runbooks доступны без поиска по личным сообщениям.
[ ] Команды безопасны и проверены.
[ ] Ясно, какие действия destructive.
[ ] Есть критерии успеха и остановки.
[ ] Указано, когда эскалировать.
[ ] Runbook имеет owner и дату проверки.

Google SRE использует launch checklists именно для систематического обнаружения пропущенных условий: persistent data требует backup, потенциальное злоупотребление — rate limiting и quotas, а сложность проверки должна соответствовать риску запуска. (Google SRE: Reliable Product Launches)


25. Runbook и playbook

Runbook

Runbook описывает конкретное operational действие.

Alert:
PaymentConfirmationLagHigh

Проверить:
1. user impact dashboard;
2. consumer lag по region;
3. rejected messages по error_code;
4. последние deployments и config changes.

Безопасные действия:
1. остановить rollout;
2. выключить new_payment_path;
3. увеличить consumers в пределах capacity limit.

Не делать:
- не очищать topic;
- не повторять messages без idempotency check.

Эскалация:
- Payments Platform primary;
- Kafka Platform secondary.

Успешное восстановление:
- lag снижается;
- final-state SLI восстановлен;
- reconciliation показывает отсутствие потерь.

Playbook

Playbook описывает координацию класса incidents:

  • роли;
  • severity;
  • каналы;
  • коммуникацию;
  • контрольные точки;
  • юридическую или security эскалацию;
  • критерий завершения.

Runbook не заменяет мышление

Он уменьшает число решений под стрессом, но не должен заставлять выполнять опасную последовательность при изменившейся реальности.

Каждый шаг должен по возможности включать:

  • цель;
  • precondition;
  • команду или действие;
  • ожидаемый результат;
  • способ проверки;
  • rollback самого действия.

26. Метрики incident management

Популярны:

MTTD — mean time to detect.
MTTA — mean time to acknowledge.
MTTM — mean time to mitigate.
MTTR — mean time to recover/resolve.

Но аббревиатура MTTR часто означает разные события. Нужно явно определить начало и конец.

Среднее может скрывать реальность

9 incidents по 5 минут
1 incident на 10 часов

дают среднее, которое не описывает ни типичный, ни катастрофический случай.

Полезнее смотреть:

  • распределение времени detection;
  • распределение времени mitigation;
  • p50 / p90 / p95;
  • impact duration;
  • error budget consumed;
  • incidents по типам причин;
  • повторяемость классов;
  • время выполнения action items;
  • долю incidents, обнаруженных пользователями;
  • pager noise;
  • долю rollback, которые реально сработали.

Метрика не должна ухудшать решение

Если команду наказывают за большой MTTR, она может раньше объявлять recovery, не завершив проверку данных. Если наказывают за количество incidents, люди перестают их объявлять.

Система измерения incident response
не должна создавать стимул скрывать incidents.

27. Полный пример: оплаченные заказы остаются Pending

Исходное изменение

Команда переводит публикацию PaymentConfirmed на новый Kafka producer. Код развёрнут под feature flag и включён для 25% трафика.

Что видят локальные dashboards

Payment API availability: 99.99%.
HTTP latency p95: 180 ms.
CPU: 42%.
Memory: 58%.
Pods: Running.

Технически всё выглядит зелёным.

Реальный пользовательский эффект

Платёж авторизован, но confirmation event отклоняется broker из-за неправильного security protocol. API уже вернул 200. Order service не получает событие, заказ остаётся Pending, пользователь повторяет оплату.

Detection

User journey metric показывает:

payment_authorized → order_confirmed

control: 99.7%
treatment: 71.4%

Одновременно растут:

  • time-to-final-order-state;
  • outbox retry count;
  • duplicate checkout attempts;
  • support contacts.

Alert

SEV-1 candidate:
checkout final-state SLO burn rate = 48
на окнах 5m / 1h.

Treatment variant значительно хуже control.
Runbook: payments/new-producer-failure.

Incident declaration

On-call объявляет incident, не дожидаясь точной root cause.

Назначаются:

  • IC — Engineering Lead;
  • OL — Payments on-call;
  • CL — Product Operations;
  • Scribe — secondary on-call.

Mitigation

  1. rollout остановлен;
  2. feature flag выключен для нового трафика;
  3. подтверждено, что старый path совместим;
  4. outbox сохранён, сообщения не удаляются;
  5. создан отдельный recovery worker для pending events.

Validation

Недостаточно увидеть падение error rate.

Команда проверяет:

  • новые checkout завершаются;
  • pending queue уменьшается;
  • payment provider и orders reconciled;
  • duplicate charges отсутствуют или выделены;
  • уведомления пользователям отправлены;
  • treatment traffic равен нулю;
  • error budget burn rate вернулся в норму.

Root cause analysis

Trigger:
включение нового producer path.

Immediate defect:
неверное значение security.protocol.

Latent conditions:
- staging broker принимал оба protocol;
- config schema проверяла тип, но не допустимое значение;
- canary gate смотрел только HTTP API;
- asynchronous final state не входил в SLO;
- flag metadata не содержала автоматический rollback condition.

Response gaps:
- первый runbook предлагал restart consumers,
  хотя проблема находилась в producer;
- Payments и Kafka teams использовали разные dashboards.

Recovery strengths:
- старый path сохранялся;
- outbox не потерял события;
- flag применялся за секунды;
- idempotency защитила повторную обработку.

Action items

Действие Тип Owner Проверка
Валидировать protocol по allowlist при startup Prevent Payments Процесс не стартует с incident-config
Добавить end-to-end canary до order_confirmed Detect Checkout Platform Canary падает при rejected event
Автоматически отключать treatment при burn rate threshold Mitigate Release Platform Game day подтверждает rollback
Объединить trace через outbox и consumer Diagnose Observability Один trace показывает полный path
Обновить reconciliation runbook Recover Payments Operations Другой on-call выполняет drill без автора

Теперь postmortem не заканчивается на фразе «неправильно указали Kafka parameter». Он изменяет систему проверки, detection, mitigation и recovery.


28. Язык лида

Когда сервис технически жив, но функция нарушена

"Infrastructure health остаётся нормальным,
но пользовательский checkout нарушен:
28% авторизованных платежей не переходят в confirmed order.
Мы считаем сервис degraded и работаем по SEV-1".

Когда root cause ещё неизвестен

"Причина пока не подтверждена.
Подтверждено воздействие на EU region и корреляция с новым rollout.
Мы остановили расширение и выключаем новый path.
Расследование producer configuration продолжается параллельно".

Когда нужен rollback

"Полное понимание defect сейчас не требуется для решения.
Предыдущая версия совместима, rollback проверен,
а impact продолжает расти. Сначала восстанавливаем функцию".

Когда rollback опасен

"Прямой rollback приложения небезопасен:
новая версия уже записала данные нового формата.
Сначала включаем compatibility reader,
после этого можем вернуть application path".

Когда alert шумит

"За месяц alert вызвал on-call 17 раз,
но только два раза потребовал действие.
Это не доказательство нестабильности людей.
Это дефект alert design. Пересматриваем SLI, threshold и channel".

Когда postmortem пытаются превратить в суд

"Действие инженера входит в timeline как факт.
Но фраза 'он ошибся' не объясняет,
почему система допустила опасную config,
почему canary её не увидел и почему rollback занял 40 минут.
Разбираем весь механизм".

Когда blameless используют для ухода от действий

"Blameless не означает, что action items можно не выполнять.
Мы не наказываем человека за сообщение фактов,
но назначенные изменения имеют owners, priority и validation".

29. Практика модуля

Упражнение 1. Построить observability map

Дан пользовательский сценарий:

Пользователь бронирует билет,
оплачивает его и получает подтверждение.

Участник должен определить:

  • critical path;
  • user-facing SLI;
  • logs на state transitions;
  • metrics;
  • trace boundaries;
  • correlation fields;
  • black-box check;
  • saturation signals;
  • dashboard;
  • alert conditions.

Упражнение 2. Разобрать alerts

Для каждого правила решить: page, ticket, notification или удалить.

1. CPU > 75% в течение 5 минут.
2. Checkout success rate ниже SLO, burn rate = 20.
3. Certificate истекает через 25 дней.
4. Один pod перезапустился, traffic не затронут.
5. Queue lag растёт и через 40 минут нарушит processing deadline.
6. Новый error появился один раз за неделю.

Нужно объяснить решение, а не только выбрать канал.

Упражнение 3. Определить SLI / SLO / SLA

Для payment service сформулировать:

  • valid event;
  • good event;
  • measurement point;
  • measurement window;
  • target;
  • error budget;
  • policy при быстром burn;
  • отличие внутреннего SLO от клиентского SLA.

Упражнение 4. Incident simulation

Сценарий:

Новая версия включена на 50%.
HTTP success не изменился.
Количество пользовательских повторов выросло.
Kafka lag растёт.
Один регион не затронут.
Support получает жалобы на двойное списание.

Участник должен:

  • объявить severity;
  • назначить роли;
  • сформулировать known / unknown;
  • выбрать mitigation;
  • написать два status updates;
  • определить validation recovery;
  • сохранить decision timeline.

Упражнение 5. Postmortem

Дан timeline и набор противоречивых свидетельств. Нужно:

  • отделить observation от reconstruction;
  • описать impact;
  • выделить trigger и contributing factors;
  • найти detection и response gaps;
  • сформулировать action items четырёх типов: prevent, contain, detect, recover;
  • исключить формулировки «быть внимательнее».

Упражнение 6. Operational Readiness Review

Участник принимает новый сервис в production responsibility и должен проверить:

  • ownership;
  • SLO;
  • capacity;
  • dependencies;
  • backup/restore;
  • deployment/rollback;
  • observability;
  • alerting;
  • on-call;
  • runbooks;
  • incident response;
  • graceful degradation.

Итог — не approve / reject, а список рисков, обязательных action items и условий запуска.


30. Итоговый артефакт: Production Responsibility Pack

После модуля участник готовит operational package для реального сервиса.

30.1. Service overview

# Service Overview: [название]

## Назначение

Какую функцию выполняет сервис?

## Пользователи

Кто зависит от сервиса?

## Critical journeys

- ...

## Ownership

- Team:
- Primary on-call:
- Secondary:
- Escalation:

## Dependencies

| Dependency | Type | Failure behavior | Owner | Fallback |
| --- | --- | --- | --- | --- |
| | | | | |

30.2. SLO document

# SLO

## SLI

- Valid event:
- Good event:
- Measurement point:
- Data source:

## Objective

- Target:
- Window:
- Segments:

## Error budget

- Budget:
- Burn-rate alerts:
- Policy:

30.3. Alert card

# Alert: [name]

## User impact

## Condition

## Severity and channel

## First checks

## Safe actions

## Dangerous actions

## Escalation

## Recovery validation

## Dashboard / Runbook

30.4. Incident state document

# Incident: [ID]

- Severity:
- Started:
- IC:
- OL:
- CL:
- Scribe:

## Impact

## Known

## Unknown

## Current mitigation

## Workstreams

| Workstream | Owner | Status | Result |
| --- | --- | --- | --- |
| | | | |

## Decision log

| Time | Observation | Decision / Action | Owner | Result |
| --- | --- | --- | --- | --- |
| | | | | |

## Next update

30.5. Postmortem

# Postmortem: [ID]

## Summary

## Impact

## Detection

## Timeline

## Technical narrative

## Trigger

## Contributing factors

## Detection gaps

## Response gaps

## What went well

## What went poorly

## Where we got lucky

## Action items

| Action | Type | Priority | Owner | Due | Validation |
| --- | --- | --- | --- | --- | --- |
| | | | | | |

31. Чек-лист лида

[ ] Я могу назвать пользовательскую функцию сервиса.
[ ] У нас есть SLI этой функции, а не только CPU и memory.
[ ] SLO содержит target, окно и правила измерения.
[ ] Error budget связан с решениями, а не только отображается.
[ ] Logs структурированы и имеют correlation context.
[ ] Metrics показывают latency distribution, errors, traffic и saturation.
[ ] Trace проходит через критические async boundaries.
[ ] Deployment version и feature flag variant видимы в telemetry.
[ ] Health checks различают startup, liveness и readiness.
[ ] Каждый page требует немедленного человеческого действия.
[ ] У каждого alert есть owner, dashboard и runbook.
[ ] On-call имеет доступ, полномочия и escalation path.
[ ] Incident можно объявить без разрешения театральной комиссии.
[ ] Роли incident response определены.
[ ] Rollback спроектирован и проверен.
[ ] Database migration не уничтожает обратимость молча.
[ ] Feature flags имеют safe defaults, owners и lifecycle.
[ ] Recovery проверяется по пользовательскому сценарию и данным.
[ ] Postmortem отделяет наблюдение от реконструкции.
[ ] Human error не используется как конечное объяснение.
[ ] Action items имеют owners, priority и validation.
[ ] Operational readiness проверена до полного rollout.

32. Главные антипаттерны

Код закончился на merge

Команда не проектирует deployment, telemetry, rollback и эксплуатацию.

Зелёный CPU объявлен здоровьем

Infrastructure metrics подменяют пользовательскую функцию.

Logs есть, найти ничего нельзя

Нет структуры, context, version и correlation ID.

Метрик слишком много, SLI нет

Система измеряет всё, кроме собственного результата.

Alert на каждое отклонение

Человека вызывают из-за странности, а не из-за необходимого действия.

On-call как героизм

Нет runbooks, secondary, полномочий и восстановления после ночных incidents.

Incident объявляют после нахождения root cause

Координация начинается тогда, когда основное время уже потеряно.

Все одновременно расследуют всё

Нет IC, workstreams и decision log.

Fix before mitigation

Пользовательское воздействие продолжается, пока команда ищет идеальное объяснение.

Rollback существует только в pipeline

Совместимость данных и реальное восстановление никогда не проверялись.

Feature flag навсегда

Ветки накапливаются, владельцы исчезают, safe default неизвестен.

Postmortem заканчивается виноватым

Назван человек, но система осталась прежней.

Blameless означает бездействие

Никто не наказан, но никто не выполняет corrective actions.

Root cause всегда один

Многопричинная система превращается в удобную линейную сказку.

Recovery равен зелёному dashboard

Не проверены данные, очереди, повторные операции и пользовательский путь.


33. Основные формулы модуля

merge ≠ delivery
deployment ≠ release
running ≠ ready
ready ≠ correct
HTTP 200 ≠ успешный пользовательский результат

telemetry ≠ observability
metric ≠ alert
alert ≠ incident
dashboard ≠ управление

mitigation ≠ root cause fix
recovery ≠ corrective action
rollback command ≠ обратимость системы

blameless ≠ безответственность
human error ≠ root cause
последнее изменение ≠ доказанная причина

SLI = измеренный уровень
SLO = целевой уровень
SLA = договорённость и последствия
error budget = 1 − SLO

локальное здоровье компонента ≠ здоровье пользовательского сценария

Главная формула:

Наблюдаемость без действия — архив.
Действие без наблюдаемости — угадывание.
Ответственность без полномочий — назначенное бессилие.
Postmortem без изменения системы — литературный отчёт об аварии.

34. Финальное различение

Слабая production culture выглядит так:

Разработчик написал код.
DevOps его выкатил.
Monitoring что-то показал.
On-call как-то починил.
Менеджер спросил, кто виноват.
Команда пошла дальше.

В этой модели причинность разрезана между функциями так, что никто не удерживает систему целиком.

Lead-level responsibility выглядит иначе:

Вот функция сервиса.
Вот пользовательский путь.
Вот SLI и допустимая граница отказа.
Вот telemetry, которая сохраняет причинность.
Вот условия page.
Вот человек с полномочиями и escalation path.
Вот безопасные механизмы rollout и rollback.
Вот режим incident command.
Вот критерий реального recovery.
Вот postmortem.
Вот изменения, которые после него появились в системе.

Лид не обещает отсутствие отказов. Он строит систему, в которой отказ ограничен, обнаружим, объясним, обратим настолько, насколько это возможно, и не исчезает из памяти сразу после восстановления графика.

Это и есть ответственность за живую систему.


Источники

Прокрутить вверх