DarkRiDDeR16 мин

Incident runbook: от симптома до rollback без догадок

НадёжностьЭксплуатация

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

Причина — runbook часто написан как список команд без условий остановки. В нём нет точного симптома, границы влияния, безопасного rollback и проверки результата. Рабочая инструкция начинается с наблюдаемого сигнала, запрещает опасные действия до сбора фактов и оставляет короткую петлю: измерить, изменить, проверить, зафиксировать.

Симптом не является причиной

Статус 500, рост latency и очередь сообщений — разные наблюдения. Они могут иметь общий корень, а могут быть независимыми последствиями. Первый экран runbook должен попросить время начала, affected endpoint, долю ошибок, baseline и scope. Запись «всё медленно» не позволяет выбрать действие или оценить улучшение.

Причину формулируйте как гипотезу с проверкой: «после изменения лимита pool выросло ожидание соединения; подтверждение — метрика pool wait и сравнение с предыдущим окном». Гипотеза может не подтвердиться. Runbook должен описывать и такой исход, иначе оператор будет подгонять данные под первую версию.

Карточка первичного сигнала
ПолеПримерЗачем нужноОшибка формулировки
Время14:05 UTC ± 5 минсопоставить deploy и метрики«сегодня»
ScopePOST /payments, region EUне трогать здоровый трафик«весь сервис»
Симптом5xx 8%, p95 1.8sизмерить baseline и эффект«сломалось»
Гипотезаpool wait выросвыбрать проверкусразу назвать виновника
Действиеrollback flag Xизменить один рычагперезапустить всё
Проверка5xx < 1% 10 минзакрыть loop«кажется лучше»

Сначала ограничить blast radius

Если изменение затронуло часть трафика, безопаснее уменьшить scope, чем сразу исправлять все слои. Отключение feature flag, остановка нового consumer или перевод небольшой доли на старый код дают обратимый шаг. Перезапуск без измерения может убрать симптом на минуту и стереть следы причины.

Rollback тоже имеет условия. Он безопасен, если старая версия читает текущую схему и понимает созданные события. Если недавно была миграция, сначала проверьте compatibility matrix. Во время incident нельзя полагаться на память о порядке выката: runbook должен содержать команду, ожидаемый эффект, риск и способ вернуть действие.

Петля incident runbook: симптом и scope ведут к проверке гипотезы, одному обратимому действию и измерению восстановления до закрытия инцидента.
Диаграмма показывает короткий рабочий цикл. Каждое действие имеет условие отката и отдельную проверку результата.

Runnable-пример: классифицируем первичный сигнал

Функция получает HTTP status, latency и error rate, затем применяет два явных порога. Она не решает, кто виноват и какой rollback безопасен. Зато оператор может проверить, что одинаковые входы дают одинаковую срочность, а порог ошибки имеет приоритет над вторичным latency-сигналом.

import { classifyIncidentSignal } from './upgrade-2027-11.mjs';

const signal = classifyIncidentSignal({
  status: 503,
  latencyMs: 820,
  errorRate: 0.08,
  latencyLimitMs: 1000,
  errorLimit: 0.05,
});
const slow = classifyIncidentSignal({
  status: 200,
  latencyMs: 1400,
  errorRate: 0.01,
});

console.log(signal.severity, signal.reason);
console.log(slow.severity, slow.reason);
// high availability-or-error-threshold
// medium latency-threshold

Порядок действий во время инцидента

  1. Запишите timestamp, scope и один измеримый симптом. Сохраните ссылку на dashboard и исходное окно сравнения.
  2. Проверьте, затронуты ли все регионы, методы и версии. Ограничьте воздействие, если есть безопасный flag или traffic split.
  3. Сформулируйте одну гипотезу и одну проверку. Не меняйте конфигурацию до того, как знаете, какой сигнал должен измениться.
  4. Выберите одно обратимое действие и запишите ожидаемый эффект, риск и условие возврата. Не запускайте пачку независимых исправлений.
  5. Подождите заранее заданное окно и сравните error rate, latency, saturation и бизнес-сигнал. «Команда завершилась» не означает восстановление.
  6. Зафиксируйте итог, оставшиеся риски и следующий diagnostic item. После стабилизации сохраните факты до очистки временных изменений.

Rollback и восстановление — разные события

Rollback возвращает конфигурацию или binary, а recovery означает, что система снова выполняет допустимую работу и данные согласованы. Можно откатить flag, но оставить очередь сообщений, двойные записи или повреждённый кэш. Поэтому после изменения нужно проверять не только 5xx, но и отставание очереди, успешность операций и консистентность данных.

Закрывать инцидент сразу после падения error rate тоже рискованно. Ошибка могла уйти на другой endpoint, а пользовательская операция остаться незавершённой. Минимальное окно наблюдения выбирается по интервалу метрики и характеру нагрузки. В runbook лучше явно написать «не закрывать, пока X и Y не стабильны N минут», чем оставлять эту оценку оператору в самый шумный момент.

Ограничения и следующий шаг

Классификатор не хранит timeline, не отправляет уведомления и не знает бизнес-критичность endpoint. NIST SP 800-61 даёт общую дисциплину incident handling, но не заменяет локальную матрицу severity и права на rollback. Thresholds в примере учебные; их нужно получить из SLO и baseline.

Следующий шаг — взять один частый alert и превратить его в карточку с симптомом, scope, гипотезой, одним действием и проверкой восстановления. Затем проиграть runbook на staging с намеренно созданным 503 и убедиться, что оператор может остановиться на каждом небезопасном шаге.

Проверяемые источники

  • NIST SP 800-61 Revision 2 — Computer Security Incident Handling Guide — NIST, revision 2, май 2012 года, Special Publication 800-61. Применение: Даёт структуру обработки инцидента: подготовка, обнаружение/анализ, containment, eradication/recovery и post-incident activity. Граница: Не задаёт вашу архитектуру, severity thresholds, on-call график и допустимое действие для конкретной системы.
  • RFC 9110 — HTTP Semantics — IETF, июнь 2022 года, RFC 9110, Standards Track. Применение: Помогает различать HTTP-статус, метод и сетевой сбой при сборе первичного симптома. Граница: Не является runbook и не заменяет метрики, логи, traces и проверку конкретного сервиса.