Можно расставить circuit breaker’ы, настроить репликацию и написать идеальные бэкапы — и всё равно превращать каждый инцидент в хаос, терять причины и повторять одни и те же ошибки, если вокруг нет процесса. Надёжность в зрелых командах — это не только код, но и дисциплина: как реагируют на инцидент, как разбирают его потом и как из разбора рождаются изменения. Причём ключевая деталь контринтуитивна: разбор должен быть безобвинительным, иначе люди начинают прятать настоящие причины, и организация перестаёт учиться. Эта статья — про SRE-сторону отказоустойчивости.
Финальная статья серии «System design: resilience» — про процесс, который заставляет технические паттерны работать. Опирается на SLO и error budgetготовится, с 13 октября. Готовые к присвоению шаблоны — шаблон постмортема и пример политики error budget — лежат в architecture/resilience/incident.
В статье
- Инцидент-менеджмент — severity, роли и одна голова на решения
- Коммуникация — тушить и объяснять это разные работы
- Почему разбор безобвинительный — не из вежливости, а по расчёту
- Анатомия разбора — таймлайн, TTD/TTR, способствующие факторы
- Action items и runbooks — как разбор превращается в изменения
- Error budget как политика — когда чинить надёжность вместо фич
- Checklist
Инцидент-менеджмент
Инцидент отличается от бага тем, что он идёт сейчас и его надо тушить параллельно с выяснением причин. Хаос возникает не от сложности проблемы, а от неопределённости: непонятно, кто главный, кто пишет пользователям и когда звать подмогу.
Severity задаёт, что происходит дальше. Полезно, когда уровень определяет не «насколько нам страшно», а конкретные обязательства: будим ли on-call немедленно, обязателен ли ведущий, как часто идёт статус. Три уровня обычно достаточно; больше — начинают спорить о классификации вместо тушения.
Роли важнее должностей:
- Incident commander (IC) — принимает решения и держит картину целиком. Он не чинит руками: как только IC уходит в отладку, инцидентом перестают управлять.
- Scribe — ведёт таймлайн в реальном времени. Задним числом восстановить точные моменты почти невозможно, а именно они потом дают TTD и TTR.
- Communications — говорит с внешним миром: статус, поддержка, руководство.
Главное правило — одна голова на решения. Не потому, что остальные не разбираются, а потому, что при нескольких центрах решений действия начинают конфликтовать: один откатывает, другой в это время правит конфиг.
Эскалация должна быть заранее описана и дешёвой: если звать подмогу считается признанием некомпетентности, звать будут поздно.
Коммуникация
Тушить и объяснять — разные работы, и их нельзя валить на одного человека. Пока инженер отвечает на вопросы «ну что там?», он не чинит.
Что работает:
- Единый канал инцидента, где идёт вся техническая работа, и отдельный поток статусов наружу.
- Регулярный ритм статусов (например, каждые 30 минут для SEV1) даже когда сказать нечего: «работаем, гипотеза такая» лучше молчания, потому что молчание порождает поток вопросов.
- Честность с пользователями. Признать деградацию дешевле, чем делать вид, что всё в порядке: доверие теряется не от сбоя, а от ощущения, что его скрывают.
Почему разбор безобвинительный
Блеймлесс — не про вежливость, а про то, откуда берётся информация. Расчёт простой: разбор питается тем, что расскажут люди. Если за рассказ наказывают, рассказывать перестанут — не из злого умысла, а из инстинкта. Причины уйдут в тень, разбор станет ритуалом, и организация потеряет способность учиться на собственных сбоях.
Практический критерий: если в разборе появилось имя человека как объяснение («Петров выкатил плохой конфиг»), формулировка ещё не доведена. Доведённая звучит как свойство системы: «конфиг попадал в прод без валидации и канареечной выкатки». Разница не косметическая — из первой формулировки следует «поговорить с Петровым», из второй — конкретное изменение, которое защитит и следующего.
Правильный вопрос про человеческую ошибку не «почему он ошибся», а «почему это было легко сделать и трудно заметить». Человеческая ошибка — это симптом устройства системы, а не причина.
Анатомия разбора
Хороший постмортем состоит из фактов, а не впечатлений:
- Таймлайн — что и когда произошло: первый симптом, момент обнаружения (и чем обнаружили — алертом или жалобой), объявление инцидента, гипотезы, смягчение, полное восстановление.
- Две величины из таймлайна. TTD (time to detect) — сколько система «горела» молча; TTR (time to recover) — сколько шли до восстановления. Большой TTD означает проблему с наблюдаемостью, а не с починкой, и лечится другими мерами.
- Способствующие факторы вместо «первопричины». Реальный инцидент — это цепочка условий: триггер (деплой, всплеск, отказ зависимости) плюс то, что позволило ему перерасти: не было таймаута, молчал алерт, устарел runbook. Поиск единственного виноватого фактора обычно останавливает разбор слишком рано.
- Что сработало хорошо. Отдельный раздел — не для настроения: удачный откат и живой runbook стоит зафиксировать, чтобы не потерять при следующей перестройке.
Готовая структура — в шаблоне постмортема из приложения к статье: architecture/resilience/incident.
Action items и runbooks
Разбор без изменений — потраченное время. Требования к action items:
- Конкретность. «Быть внимательнее» и «улучшить мониторинг» невыполнимы и непроверяемы. Выполнимо: «добавить таймаут и предохранитель на вызов X», «алерт на burn-rate SLO».
- Владелец и срок. Без них пункт не существует.
- Приоритет по эффекту, а не по простоте: сначала то, что убирает способствующий фактор, а не то, что быстрее закрыть.
Отдельный класс результата — runbook: превращение разобранного инцидента в воспроизводимую реакцию. Смысл в том, чтобы следующее дежурство чинило по шагам, а не выводило причину заново в три часа ночи. Runbook стареет, поэтому его проверяют на учениях — как и план восстановления в DR.
Error budget как политика
Спор «фичи против стабильности» решается не силой убеждения, а заранее согласованным правилом. Error budget — допустимая доля неуспеха по SLO (при 99.9% за месяц это примерно 43 минуты недоступности). Пока бюджет есть — катим фичи и принимаем разумный риск; исчерпан — замораживаем фичи и чиним надёжность, пока он не восстановится.
Ценность в том, что решение принимается не в момент спора, а заранее и всеми сразу. Заморозка перестаёт быть чьим-то волевым актом и становится тем, на что команда уже согласилась. Механика SLI/SLO, burn-rate и алертов — в статье про SLO и error budgetготовится, с 13 октября; пример политики с порогами — в приложении к этой.
Связь с постмортемом прямая: инцидент, сжёгший заметную долю бюджета, требует разбора, а его action items — первые кандидаты в работу во время заморозки. Чинить логично ровно то, что бюджет и потратило.
Checklist
- Severity определяет обязательства (будить/не будить, ритм статусов), а не эмоцию.
- Роли назначаются явно; IC управляет и не чинит руками; решения — одна голова.
- Эскалация описана и дешёвая: звать подмогу не стыдно.
- Тушение и коммуникация разведены; статусы идут по ритму даже без новостей.
- Постмортем блеймлесс: в объяснениях свойства системы, а не фамилии.
- В разборе есть таймлайн, TTD/TTR и цепочка способствующих факторов, а не одна «первопричина».
- Action items конкретны, с владельцем и сроком; повторяющийся класс инцидентов превращён в runbook.
- Политика error budget согласована заранее: когда катим, когда замораживаем и кто снимает заморозку.
Первоисточники
- Google SRE Book: Managing Incidents и Postmortem Culture — роли, блеймлесс-разбор, шаблоны.
- Google SRE Workbook: Error Budget Policy — как выглядит согласованная политика.
- Шаблоны к статье — в architecture/resilience/incident.
Комментарии