Systematic Troubleshooting
«Сервис лежит, что-то делаем» — режим, в котором команда два часа подряд меняет конфиги, рестартует поды и откатывает feature flags, пока в какой-то момент оно не «починилось само». Через неделю повторяется то же самое. Никто ведь не знает, что именно сработало в прошлый раз. Systematic Troubleshooting — это дисциплина разбора неизвестной поломки: формулируем гипотезу, выбираем измерение, которое её подтвердит или опровергнет, фиксируем результат, идём дальше. Без такой дисциплины опыт не накапливается даже у сильных инженеров — «починил наугад» не оставляет следа в голове. Этот лист про методологию (USE, RED, четыре золотых сигнала, работа от гипотезы, деление пополам, таймер на проверку), а не про конкретные инструменты.
Граница: Incident Response — координация разбора (роли, сводки, war room); здесь — как именно копать внутри своей роли. Performance & Profiling — разбор симптома «медленно» через профиль и flame graph; здесь — общая методология для любого симптома: медленно, падает, не подключается, теряет данные. Blameless Postmortem — разбор после; здесь — во время. Runbooks — что делать по известному алерту; здесь — что делать, когда runbook не помог или сценария нет вовсе.
Что должен уметь
Заголовок раздела «Что должен уметь»Главный навык на уровне L4 — держать одну гипотезу за раз и ставить таймер на её проверку. По моим наблюдениям, типовая ошибка инцидента — менять три вещи одновременно «чтобы быстрее», а потом не знать, что из этого помогло, а что сломало. Опытный инженер отличается тем, что проговаривает вслух: «гипотеза — падает резолвер в kube-dns; проверяю запросом из соседнего пода; десять минут; не подтвердится — переключаюсь на ingress». Это не философия, а конкретная привычка говорить, и она видна прямо в переписке инцидентного канала.
L3
- Различает симптом и причину: «клиенты получают 502» — симптом; «пул к вышестоящему сервису исчерпан» — следствие; «шторм повторов от соседа» — причина. Не путает «что я вижу» с «почему это происходит».
- Применяет деление пополам: в цепочке
клиент → балансировщик → ingress → приложение → базапроверяет середину — участок «приложение — база», — чтобы одним шагом отсечь половину цепочки. Не идёт линейно от клиента. - Записывает каждую проверку в журнал инцидента со временем: что проверил, что увидел. Чтобы IC и сменщик видели, куда уже копали.
L4
- Применяет четыре золотых сигнала (задержка, трафик, ошибки, насыщение) и RED (поток, ошибки, длительность) на уровне приложения, USE (загрузка, насыщение, ошибки) на уровне ресурса — первым проходом, ещё до чтения кода. По моим наблюдениям, бо́льшая часть ситуаций «непонятно что» снимается этим проходом за пять минут.
- Формулирует гипотезу до измерения, а не наоборот: «думаю, что X, потому что Y; проверяю через Z». Если измерение не отвергает и не подтверждает гипотезу — оно бесполезно, надо менять.
- Ставит таймер на каждую гипотезу, пятнадцать-тридцать минут. Не подтвердилась — следующая, а не «ещё чуть-чуть покопаю».
- Не меняет два параметра сразу. Если нужно откатить фичу и перезапустить под — сначала одно, потом другое; иначе непонятно, что помогло.
L5
- Различает простые, сложные, запутанные и хаотические ситуации по Cynefin (Dave Snowden). Простая — отработать runbook; сложная — привлечь эксперта; запутанная — несколько безопасных к провалу проб параллельно; хаотическая — любое действие, чтобы выйти из хаоса. Путаница между категориями — частая ошибка даже у опытных: копаться там, где сработает runbook, или гонять runbook по системе, которая давно вне его сценария.
- Снимает снимок состояния до гашения: дамп кучи, дамп горутин,
kubectl describe, выгрузка свежих метрик,dmesg. Перезапуск, добавление реплик и переключение часто уничтожают улики; опытный инженер помнит снять снимок заранее. Без него постмортем превращается в «не воспроизвели». - Помнит про базовые вероятности: слышишь топот — думай про лошадей, а не про зебр. Свежий деплой полчаса назад — начинать с него, а не с теории про космические лучи. Я регулярно вижу разборы, где гипотеза «сложное и новое» побеждает гипотезу «свежий коммит» только потому, что вторая скучная.
- Различает триггер и причину: «деплой X сломал» — триггер; «у нас нет постепенной выкатки, поэтому любой плохой деплой сразу оказывается в проде» — причина. Постмортем по триггеру даёт «не делайте таких коммитов», постмортем по причине — системную меру.
L6+
- Строит культуру разбора в команде: журнал инцидента как обязательный артефакт, структурированная передача смены, разбор после инцидента с вопросом «как мы копали», а не только «что чинили». Учит методу, а не починке конкретного бага.
- Связывает разбор с базой постмортемов: видит повторяющиеся сюжеты между инцидентами (третий раз задержки в хвосте после деплоя — значит, нужна канарейка), а не считает каждый инцидент уникальным.
- Поднимает Game Day и «колесо неудач» как тренировку: учебный инцидент отрабатывает методологию без риска для прода.
Материалы
Заголовок раздела «Материалы»- David J. Agans — Debugging: The 9 Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems (AMACOM, 2002). Каноническая короткая книга про методологию: понять систему, воспроизвести отказ, перестать думать и посмотреть, делить пополам, менять по одному, вести журнал, проверить, воткнута ли вилка, позвать свежий взгляд, убедиться, что действительно починил. Если выбирать одну — эту. Я регулярно ловлю себя на нарушении одного из правил прямо во время инцидента.
- Betsy Beyer et al. — Site Reliability Engineering, глава 12 «Effective Troubleshooting» (O’Reilly, 2016). Разбор от Google: разделение симптома, причины и триггера, работа от гипотезы, чек-листы. Доступна онлайн бесплатно.
- Brendan Gregg — Systems Performance: Enterprise and the Cloud (Addison-Wesley, 2-е изд., 2020). Метод USE описан здесь подробно, плюс конкретные методики для процессора, памяти, диска и сети. Пересекается с Performance & Profiling, но методологическая часть применима шире.
- Sidney Dekker — The Field Guide to Understanding «Human Error» (CRC Press, 3-е изд., 2014). Не про отладку, но фундамент: почему «человек ошибся» — это симптом, а не причина, и почему разбор не должен останавливаться на «забыл
--dry-run». - Brian Kernighan, Rob Pike — The Practice of Programming (Addison-Wesley, 1999). Глава про отладку — короткая, но классическая: как читать стек, как искать делением пополам в коде и почему «скорее всего, сломали недавние изменения» — разумная гипотеза по умолчанию.
Статьи и доклады
Заголовок раздела «Статьи и доклады»- John Allspaw — Trade-Offs Under Pressure: Heuristics and Observations of Teams Resolving Internet Service Outages (магистерская работа, Lund University, 2015). Полевое исследование того, как опытные инженеры разбирают инциденты в проде. Длинно, но если цель — вырастить у себя L5, читать обязательно.
- Brendan Gregg — The USE Method. Один экран, один метод, применим к любой системе. Каноника.
- Tom Wilkie — The RED Method: Key Metrics for Microservices Architecture (Weaveworks, 2018). Аналог USE на уровне приложения: поток, ошибки, длительность. По моим наблюдениям, RED — самый частый первый дашборд для нового сервиса.
- Richard I. Cook — How Complex Systems Fail (1998, восемнадцать пунктов). Не про отладку напрямую, но задаёт фон: «корневая причина» — языковой конструкт, а не объективная категория. Это меняет то, как формулируются выводы.
- Charity Majors — Observability — A 3-Year Retrospective (2020). Почему мониторинг известных проблем через дашборды — не то же самое, что разбор неизвестных через данные высокой кардинальности. Ровно эта граница и отделяет «есть runbook» от «нужен систематический разбор».
- Dave Snowden — A Leader’s Framework for Decision Making (HBR, 2007). Cynefin для неакадемической аудитории, восемь страниц.
Инструменты
Заголовок раздела «Инструменты»Этот лист про методологию, инструменты живут в соседних (Networking, Operating Systems, Shell & CLI Craft, Performance & Profiling). Но три штуки относятся к самому процессу разбора:
- Журнал инцидента в общем документе, в холсте Slack или в выделенном канале — текстовая хроника с отметкой времени на каждой проверке. Это одновременно фиксация состояния, материал для передачи смены и сырьё для постмортема. Без него постмортем превращается в «вроде что-то делали».
- Доска гипотез (маркерная доска, Miro или простой файл с чек-листом) — список гипотез с пометками «подтверждена», «опровергнута», «не проверяли». По моим наблюдениям, физически выписанный список спасает от типовой ошибки «прыгаем между тремя гипотезами и ни одну не закрываем».
- Чек-листы методик — USE, RED и золотые сигналы под рукой: распечатка, страница в вики, закладка в Slack. Идея не в том, чтобы вспоминать в стрессе, что мерить, а в том, чтобы пробежать готовый список.
- Анти-инструмент: «крутим конфиги наугад без гипотезы». Не инструмент, а антипаттерн. Самый частый источник историй «починили, но не знаем чем».
Best practices
Заголовок раздела «Best practices»Главный публичный кейс — исследование Allspaw на материале Etsy. Сначала как технический директор Etsy, потом в Adaptive Capacity Labs, John Allspaw задокументировал: опытные инженеры во время инцидентов не «знают ответ» — они быстрее остальных формулируют рабочую гипотезу, быстрее её опровергают и переходят к следующей. Это не интуиция и не «больше опыта», а конкретная привычка проговаривать, и она тренируется. «Колесо неудач» в Google (см. SRE Book) — институционализированная форма такой тренировки: новичок получает учебный инцидент, опытный играет роль системы и отвечает на вопросы. Тренируется тут методология, а не знание конкретного бага.
Из этого вырастают четыре правила, которые я считаю базовыми. Гипотеза идёт до измерения: если не получается сформулировать, что именно подтвердит или опровергнет очередная команда, — не набирайте её. «Посмотрю логи» — не гипотеза. Меняется одно за раз, потому что одновременный откат вместе с перезапуском и переключением флага честно приводит к «починилось, не знаем чем».
Третье правило дороже всего стоит, когда его нарушают. Снимок состояния снимается до гашения: дамп кучи, свежие метрики, kubectl describe, dmesg — всё до того, как перезапуск сотрёт следы. Тридцать секунд сейчас экономят неделю разговоров «не воспроизвели». И последнее — таймер. По пятнадцать-тридцать минут на гипотезу, дальше следующая; без таймера полчаса незаметно превращаются в два часа в кроличьей норе.
Симптом, причина и триггер — три разных вопроса. Симптом — то, что видит клиент или дашборд: «502 от ingress», «p99 вырос до восьми секунд», «отставание потребителя Kafka растёт». Причина — почему так происходит на уровне системы: «ingress ловит таймаут, потому что в приложении кончился пул, потому что база держит блокировки». Триггер — что в этот раз запустило цепочку: «деплой полчаса назад добавил запрос в цикле». Я регулярно вижу разборы, где IC останавливается на триггере, а команда теряет причину — «у нас нет канареечной выкатки, поэтому любой плохой деплой сразу падает в прод». Разбор по триггеру даёт правило «не делайте таких коммитов», разбор по причине даёт системное изменение. См. Blameless Postmortem.
Деление пополам важнее линейного обхода. В цепочке клиент → CDN → балансировщик → ingress → приложение → кеш → база инстинкт велит идти от клиента: проверить DNS, потом TLS, потом балансировщик. За шаг исключается один компонент. Деление пополам — проверить участок «приложение — база» напрямую: за один шаг ровно половина цепочки либо здорова, либо нет. Топология неважна. Стек неважен. Размер системы тоже, и именно поэтому приём переносится с монолита на десяток сервисов без единой поправки, а разница в скорости разбора, по моим наблюдениям, кратная.
USE, RED и золотые сигналы дополняют друг друга, а не конкурируют. Это просто разные уровни. USE (Brendan Gregg) — про ресурсы: для процессора, памяти, диска и сети смотрим загрузку, насыщение и ошибки. RED (Tom Wilkie) — про сервисы и их ручки: поток, ошибки, длительность. Четыре золотых сигнала из SRE Book — синтез: задержка, трафик, ошибки, насыщение. Я регулярно вижу, как команда берёт один метод и считает, что этого достаточно. На деле USE говорит «диск в полке», RED — «вот эти ручки деградировали в этот период», золотые сигналы — «сведи одно с другим и сравни с SLO».
Не доверяй ощущению «тут всё работало, проверять не надо». Allspaw зафиксировал у опытных инженеров любопытный приём: они специально перепроверяют то, что считают исправным. «Я уверен, что с балансировщиком порядок — значит, проверю его первым». Это контринтуитивно: тратишь время на заведомо здоровое. Зато снимает слепое пятно. По моим наблюдениям, «непонятно почему» часто прячется именно в компоненте, который никто не смотрит, потому что «он же работает».
Починил — проверь, что действительно починил. Главное правило Агенса: не убедился — значит, не починил. После гашения идёт проверка: воспроизвести исходный симптом, если это безопасно, увидеть, что SLI вернулся к норме, убедиться, что не вылезли вторичные ошибки. Я регулярно вижу инциденты, которые закрыли, а через двадцать минут открыли снова: гашение замаскировало симптом, но не тронуло причину.
Проговорить свою модель вслух — бесплатный приём, которым мало кто пользуется. Вслух или письменно в журнал опишите, как, по-вашему, устроен путь запроса: идёт через X, потом Y, потом Z. Часто на середине фразы выясняется, что модель разошлась с реальностью — Z выпилили полгода назад, и никто этого не помнит. Опытные так делают, начинающие стесняются.
Не всякая поломка — отладка. Если runbook уже есть, ситуация простая: отработать сценарий и не тратить время на «понять». Если знает эксперт — позвать эксперта, а не изобретать. Если не понимает никто и система ведёт себя нелинейно, работает другой режим: несколько безопасных проб параллельно — канарейка с одним флагом, минимальный откат, добавление реплик. А если всё горит и думать некогда, сначала любое действие, лишь бы выйти из хаоса. Ошибаются в обе стороны и опытные тоже: начинают исследовать там, где есть готовый сценарий, или гоняют сценарий по системе, которая давно за его пределами.
Связанные листья
Заголовок раздела «Связанные листья»- Incident Response — координация во время инцидента (роли IC, оператора, коммуникации); здесь — методология, которую применяет тот, кто копает.
- Blameless Postmortem — разбор после; разделение симптома, причины и триггера там и здесь одно и то же.
- Runbooks — готовый сценарий по известному алерту; систематический разбор начинается там, где сценарий не помог или его нет.
- Performance & Profiling — разбор «медленно» через flame graph и профиль; здесь — общая методология для любого симптома.
- Networking — сетевая диагностика как поддомен;
tcpdump,mtr,dig— инструменты, методология применения та же. - Operating Systems — то, что снимают до гашения на уровне системы:
dmesg,/proc, данные eBPF. - SLI-based Alerting / Symptom vs Cause Alerting — алерт сообщает симптом; задача разбора — пройти от симптома к причине.
- Game Day — тренировка методологии на учебном инциденте, без риска для прода.
- Postmortem Database — узнавание повторяющихся сюжетов; на уровне L6 разбор опирается на историю, а не только на «здесь и сейчас».
Открытые вопросы
Заголовок раздела «Открытые вопросы»Три темы просятся в отдельные листья. Разбор в распределённых системах (TBD) — трассировка как инструмент, частичные отказы, обнаружение расщепления кластера, восстановление причинно-следственной цепочки между сервисами. Сбор состояния до гашения (TBD) — что именно снимать: дампы кучи, горутин и потоков, снимки eBPF, логи до ротации; сейчас это один пункт в L5, а материала там на целый лист. Когнитивные искажения при разборе (TBD) — привязка к первой версии, перевес свежих событий, поиск подтверждений — и как ловить это в коллеге и в себе.
Чего я не знаю — как правильно тренировать этой методологии новичков, не пуская их в реальные инциденты. «Колесо неудач» — один путь. Если есть другие, расскажите через PR.