Управление инцидентами
Как backend-команда реагирует на production-инциденты: кто ведёт,
как коммуницирует, что пишет после. Эта страница — конвенция, не
how-to: она определяет роли, severity-классы, шаблон post-mortem’а.
Конкретные процедуры для типов инцидентов — в
../troubleshooting/. Конкретные runbook’и
деплоя/отката — ../how-to/deploy-service
/ ../how-to/rollback-deploy.
Цель страницы — чтобы инженеры не теряли время на «как правильно сказать в канал» и «что писать в отчёт», пока идёт реальный инцидент.
Содержание
- Severity классы
- Роли
- Жизненный цикл инцидента
- Коммуникация
- Mitigation vs root cause fix
- Post-mortem
- Шаблон post-mortem
- Action items
- Blameless review
- Отслеживание и повторяемость
- Что НЕ делать
- Связанные разделы
Severity классы
Три уровня. SEV выставляется на старте инцидента, может быть повышен, но не понижается до post-mortem’а.
| SEV | Критерий | Реакция | SLA старта реакции |
|---|---|---|---|
| SEV-1 | Полный outage одного из core-сервисов (user/auth, review, media) для ≥ 50% пользователей. Или: утечка данных / security incident. | Page on-call немедленно + lead-инженер + incident-commander. Остановить deploy’и. | ≤ 5 мин |
| SEV-2 | Fast-burn SLO alert (see slo-and-budget). Частичная деградация (один downstream, один endpoint). Saga failed-compensation (см. ../troubleshooting/saga-failed-compensation). | Page on-call + заморозка deploy’ев сервиса. | ≤ 15 мин |
| SEV-3 | Slow-burn SLO alert. DLQ прирост без user-impact. Медленный endpoint вне SLO. | Ticket, разбор в ближайший рабочий день. | ≤ 24ч |
Не-SEV (WARN-уровня): метрика cardinality растёт,
process_open_fds / max > 0.7, backup drift. Открывается issue, не
объявляется инцидент.
Повышение SEV — право incident commander’а или lead-инженера. Downgrade — только в post-mortem’е после полного разбора (не «кажется, это уже не так страшно»).
Роли
На любом SEV-1/SEV-2 инциденте назначаются:
- Incident Commander (IC). Ведёт инцидент: принимает решения (откатывать/чинить вперёд, эскалировать, объявлять resolved), отвечает за timeline. Не обязан писать код; сидит в канале и синхронизирует людей. Для SEV-1 — lead-инженер backend или явный delegate. Для SEV-2 — on-call дежурный.
- Operations (Ops). Делает руками:
kubectl, SQL, CI-запуски. Обычно — автор последнего релиза или специалист по затронутой системе. IC и Ops могут быть одним человеком на SEV-3, но на SEV-1/2 лучше разделять. - Communications lead (Comms). Пишет в общий канал статусы, обновляет status-page (если есть), держит stakeholders в курсе. На SEV-3 не нужен — IC совмещает.
- Scribe. Пишет timeline событий в канале или wiki-doc. Часто IC или отдельный volunteer. Без scribe’а post-mortem потом пишут по памяти с пробелами.
Роли объявляются явно: «IC — Islam, Ops — Anar, Scribe — я». Не предполагай, что «очевидно, кто что делает».
Жизненный цикл инцидента
Этапы:
- Alert. Прилетел page / ticket / report от пользователя.
- Acknowledge + SEV + roles. В течение SLA старта реакции:
- Кто-то первый отвечает в on-call канале.
- Объявляется SEV.
- Назначаются IC / Ops / Comms.
- Diagnostics. Cмотрим
failure-modes-matrix, metric/log/trace, определяем scope. - Immediate mitigation. Откат релиза, circuit-breaker, rate-limit downstream’а, переключение трафика на другой кластер. Цель — снизить impact, не исправить root cause.
- Verify mitigated. Метрики вернулись к baseline, SLO не горит. Выждать 15–30 минут под нагрузкой, прежде чем объявлять resolved.
- Announce resolved. Comms пишет в канал: «Инцидент resolved в HH:MM UTC. Root cause: X. Post-mortem: Y». Deploy’и могут быть разморожены.
- Post-mortem. В течение 3 рабочих дней (SEV-1) / 5 дней (SEV-2) — документ готов, review встреча проведена.
Коммуникация
Один канал на инцидент — общий backend on-call канал (или выделенный incident-channel, если настроен). Не плодить мини-чаты: кто-то всегда теряется.
Формат статусов
Один человек (Comms / IC) пишет обновления в формате:
[HH:MM UTC] [SEV-2] SUMMARY: review-service 5xx rate 4% for /v1/reviews
IMPACT: ~20% POST /v1/reviews failing; affected users unknown yet
WHAT WE KNOW: rollout v1.4.2 at 14:32; fast-burn SLO alert at 14:41
CURRENT ACTION: rolling back to v1.4.1 via infra-repo revert
NEXT UPDATE: 15:10 UTC or when mitigation verified- Каждые 20–30 минут на SEV-1/2, даже если «ничего нового». Тишина воспринимается как «инцидент разгорается», а не «всё под контролем».
- Когда mitigated — явное сообщение «mitigated at HH:MM, monitoring».
- Когда resolved — явное «resolved at HH:MM, next post-mortem by YYYY-MM-DD».
Что НЕ писать
- Имена ответственных за bad-merge («это Иван выкатил»). На этапе инцидента это не помогает; на этапе post-mortem’а — blameless review (см. §Blameless review).
- Догадки вместо фактов. «Возможно, из-за миграции» — только если уже проверили; иначе распространится как факт.
- Спекулятивный scope. «Мы потеряли данные 1000 пользователей» — только после подтверждения из query. До этого — «scope под оценкой».
Status-page для внешних
Если у сервиса есть public status-page (через Cloudflare / statuspage.io), Comms обновляет её на SEV-1 всегда и на SEV-2 при user- observable impact. Формулировки для внешних:
- Investigating — в течение 15 минут от старта.
- Identified — когда mitigation запущен.
- Monitoring — когда mitigated.
- Resolved — когда 30 минут зелёно.
Mitigation vs root cause fix
Mitigation — действие, возвращающее сервис в рабочее состояние, без понимания почему сломалось. Примеры: откат релиза, рестарт pod’а, скейлинг вверх, изоляция bad-node.
Root cause fix — исправление самой причины. Пишется code-change
- test, проходит обычный PR-flow.
Правила:
- На инциденте — mitigation, не root cause. Быстрее вернуть сервис в норму, чем красиво починить.
- Root cause fix идёт после инцидента, как ordinary PR, с ссылкой на post-mortem.
- Единственное исключение — когда mitigation невозможен без fix’а
(редко). В таком случае hotfix проходит staging coordinate’ом
(см.
../how-to/deploy-service), не «прямо в prod». - Mitigation не закрывает тикет. Инцидент закрывается, когда root cause исправлен и action items из post-mortem’а закрыты.
Post-mortem
Обязателен для SEV-1 и SEV-2. Для SEV-3 — на усмотрение IC:
если root cause очевиден и системный (например, пропущенный
resp.Body.Close()) — короткий discussion в PR, не полный
post-mortem.
Сроки:
- SEV-1: документ готов + review-встреча в 3 рабочих дня.
- SEV-2: в 5 рабочих дней.
Пропуск срока — явный сигнал, что команда нагружена: on-call rotation пересматривается, новые feature-задачи приостанавливаются до разгрузки.
Место: infra-репо, docs/post-mortems/YYYY-MM-DD-<slug>.md.
Каждый постmortem — отдельный файл; именуется датой инцидента +
коротким slug’ом (2026-04-20-review-5xx-rollout). Не складывать в
wiki: нужен версионный контроль и возможность ссылаться из кода и
из handbook’а.
Шаблон post-mortem
# Post-mortem: <short title>
**Date of incident:** YYYY-MM-DD
**Severity:** SEV-<N>
**Duration:** HH:MM – HH:MM UTC (XXm)
**Impact:** <one-line summary>
**Author:** <name>
**Reviewers:** <names>
## Summary
Двух-трёх абзацев про что произошло, для человека, который зашёл по
ссылке впервые. Техническая суть + business-impact.
## Timeline (UTC)
| Time | Event |
|---|---|
| HH:MM | Deploy v1.4.2 started |
| HH:MM | First alert: ReviewAvailabilityFastBurn |
| HH:MM | IC assigned (Islam), Ops (Anar) |
| HH:MM | Initial hypothesis: rollout regression |
| HH:MM | Rollback initiated via infra revert |
| HH:MM | Rollback deployed to all pods |
| HH:MM | Error rate back to baseline |
| HH:MM | Incident resolved, monitoring |
Timeline живой из on-call канала; scribe пишет по ходу, в
post-mortem вставляется почти дословно.
## Impact
- **Users affected:** <estimate or measured>. Источник оценки.
- **Requests failed:** <number or rate × duration>.
- **Error budget consumed:** X% of monthly budget for review-service.
- **Downstream impact:** что сломалось в соседних сервисах
(например, «notification-service не получил 120 событий `review.
created` за окно, реплицируются через replay»).
## Root cause
Что именно было не так. Ровно один root cause; если кажется, что
их несколько — сгруппируй или выбери main + contributing factors.
## Contributing factors
Что ещё пошло не так, что **усугубило** root cause (не cause сам
по себе). Например: пропущенный staging-тест, медленный alert,
отсутствие runbook'а у ops-дежурного.
## Detection
- Как инцидент был обнаружен? (alert / user report / internal
observation)
- Задержка между «реальное начало» и «alert сработал»?
- Что можно было бы заметить раньше?
## Response
- Что сработало хорошо в реакции? (быстрый откат, чёткие роли,
готовый runbook).
- Что замедлило? (не было runbook'а для этого сценария, alert
указал в неправильный сервис, отсутствовал IC).
## Action items
| # | Item | Owner | Deadline | Issue |
|---|---|---|---|---|
| 1 | Add CI test for rollout-compatibility | Anar | 2026-05-01 | [#123] |
| 2 | Update rollback runbook with this scenario | Islam | 2026-04-28 | [#124] |
| 3 | Tighten fast-burn threshold for review-service | Backend lead | 2026-05-10 | [#125] |
Каждый action item — **отдельный issue** в соответствующем репо. Не
list в post-mortem'е без issue — потеряется.
## Lessons learned
- Что нового узнали о системе.
- Что стоит добавить в `CLAUDE.md` / handbook как общее правило.
- Что сказать новым инженерам при onboarding'е.Шаблон — обязательная минимальная структура. Больше секций можно добавить (например, «Why it took so long to mitigate»), меньше — нельзя.
Action items
Правила:
- Owner — один человек, не команда («backend team» → потеряется).
- Deadline — конкретная дата, не «в ближайшее время».
- Issue в репо — action item без issue не существует.
- Приоритет. P0 = до следующего deploy’а; P1 = до конца спринта; P2 = в бэклог. P0 блокирует feature-work затронутой области.
- Tracking. Раз в две недели backend-lead проходит по старым post-mortem’ам и выписывает открытые action items. Если они не двигаются — это входит в retrospective.
Blameless review
Post-mortem review — о системе, не о людях. Правила:
- Не используй имена как причины. «Иван пропустил тест» → «у нас не было CI-guard’а на этот класс регрессий, и ручная проверка не сработала».
- Предполагай, что люди сделали лучшее, что могли в своём контексте. Если они ошиблись, это сигнал: контекст был неполный, инструменты подвели, чеклист не работал.
- Вопрос «почему» задаётся 5 раз, но к процессу, не к человеку. «Почему регрессия прошла staging?» → «Потому что тест на этом случае отсутствовал» → «Почему тест отсутствовал?» → …
- Приглашай тех, кто был вовлечён, не «выставляй на суд». Цель review — чтобы все узнали, как работает система, не чтобы кого-то наказать.
Если review превращается в разборки — IC останавливает и возвращает в технический режим. Если systemic problem — тиму стоит пересмотреть процесс самого review, не post-mortem.
Отслеживание и повторяемость
- Квартальный review всех post-mortem’ов: backend-lead просматривает все инциденты квартала, выделяет паттерны («последние 3 инцидента — миграции expand-contract», «forwarder lag три раза подряд»). Это — вход в планирование следующего квартала: что улучшать в tooling/процессе.
- Метрики: количество инцидентов per severity, MTTA (mean time to acknowledge), MTTR (mean time to resolve), action-items-closed- rate. Не цель — минимизировать число инцидентов (0 = значит, мы плохо alert’им), а минимизировать MTTR и улучшать action-items- closed-rate.
- Отзыв в процесс: если две инцидента из одного источника (миграции, rate-limit, один downstream) — root cause в процессе, не в случае. Этот root cause выходит в conventions / checklists.
Что НЕ делать
- Не объявлять «всё нормально» до явного resolved + 30 минут monitoring. Иначе инцидент повторяется через час, и команда снова собирается с холодного.
- Не откладывать post-mortem «на спокойное время». Контекст забывается за неделю; в 3 рабочих дня post-mortem качественнее и короче.
- Не писать post-mortem в шаблонно-пустом стиле. Если нет action items — это не post-mortem, это отчёт. У любого инцидента есть что улучшить в процессе.
- Не обсуждать «кто виноват» до и во время инцидента. После — только через blameless-обсуждение процесса.
- Не закрывать инцидент, пока mitigation active. «Мы откатили, всё работает» — это mitigation, root cause ещё не исправлен; инцидент в «mitigated», не «resolved», пока fix не смержен.
- Не прятать post-mortem. Доступен всем в компании (backend shares, минимум команде), не «only for leads». Иначе знание не распространяется.
Связанные разделы
slo-and-budget— SLO burn-rate alert’ы как типичный триггер SEV-2.../how-to/deploy-service— pre-deploy чеклист включает «is there an active incident?».../how-to/rollback-deploy— процедура mitigation’а через откат.../troubleshooting/failure-modes-matrix— для первичной диагностики multi-symptom инцидента.../troubleshooting/saga-failed-compensation— пример runbook’а, который обязательно упоминается в post-mortem’е при срабатывании alert’а.graceful-degradation— контракт сервиса при деградации, помогает корректно оценить impact.