Анализ коренных причин
Updated Jul 2026
Поиск настоящей причины, а не очевидной
Анализ коренных причин (RCA), который останавливается на первом правдоподобном объяснении, — это не анализ, а догадка. Цель RCA — не найти виноватого или что-то залатать. Цель — понять, почему система позволила произойти сбою, и изменить систему так, чтобы подобные сбои не могли повториться. Разница между командой, у которой постоянно повторяются одни и те же типы инцидентов, и командой, которая действительно улучшается, заключается в качестве их анализа коренных причин.
Фреймворки RCA
Метод «5 Почему»
Простейшая и наиболее широко используемая техника RCA. Начните с проблемы и спрашивайте «почему» повторно, пока не дойдёте до коренной причины, которая является системной, а не симптоматической.
Пример: Продакшен-сбой из-за исчерпания пула соединений с базой данных
| Уровень | Вопрос | Ответ |
|---|---|---|
| Проблема | Почему приложение упало? | Пул соединений с базой данных был исчерпан |
| Почему 1 | Почему пул соединений был исчерпан? | Медленный запрос удерживал соединения более 30 секунд |
| Почему 2 | Почему запрос был медленным? | Запрос выполнял полный скан таблицы с 50 миллионами строк |
| Почему 3 | Почему был полный скан таблицы? | В запросе отсутствовал индекс на колонке created_at |
| Почему 4 | Почему индекс отсутствовал? | Миграция, которая должна была добавить индекс, завершилась с ошибкой молча |
| Почему 5 | Почему миграция завершилась молча? | Наш инструмент запуска миграций не создаёт алерты при сбоях; он пишет в лог, который никто не мониторит |
Коренная причина: Сбои миграций не мониторятся и не создают алерты. Способствующая причина: Нет тестирования производительности запросов, которое ловит медленные запросы до продакшена.
Корректирующие действия:
- Добавить алертинг для сбоев миграций (предотвращает этот класс проблем)
- Добавить отсутствующий индекс (исправляет конкретную проблему)
- Добавить тестирование производительности запросов в CI-пайплайн (ловит медленные запросы раньше)
Типичные ошибки с методом «5 Почему»:
| Ошибка | Проблема | Исправление |
|---|---|---|
| Остановка слишком рано | «Запрос был медленным» — это симптом, не коренная причина | Продолжайте спрашивать «почему» до тех пор, пока не дойдёте до сбоя процесса или системы |
| Только одна цепочка | Сложные инциденты имеют несколько способствующих причин | Спрашивайте «почему» от нескольких начальных точек |
| Приход к человеку | «Потому что Алиса не добавила индекс» обвиняет человека, а не систему | Спросите, почему система позволила этому произойти |
| Слишком абстрактно | «Потому что наш процесс плохой» слишком расплывчато для действий | Будьте конкретны: какой процесс, какой пробел, какое изменение |
Диаграмма Исикавы (рыбья кость)
Диаграмма рыбьей кости организует потенциальные причины по категориям, что полезно для сложных инцидентов с множеством способствующих факторов.
┌── Process ──────┐
│ No migration │
│ monitoring │
│ │
┌── People ──┤ ┌── Tools ────┤
│ No query │ │ No slow │
│ review │ │ query │
│ process │ │ detection │
│ │ │ │
Problem: ─────┤ ├───┤ ├───→ Database
Database │ │ │ │ Outage
Outage │ │ │ │
│ │ │ │
└── Env ─────┤ └── Testing ──┤
Staging DB│ No load │
has 1K │ testing │
rows, not │ with │
50M │ production │
│ data │
│ volumes │
└─────────────────┘
Стандартные категории диаграммы рыбьей кости (6 М):
- Methods (Методы): Процессы, процедуры, политики
- Machines (Оборудование): Инструменты, инфраструктура, среды
- Materials (Материалы): Данные, входные данные, зависимости
- Measurements (Измерения): Мониторинг, алертинг, метрики
- Manpower (Кадры): Навыки, обучение, штат
- Mother Nature (Внешние факторы): Внешние факторы, сторонние сервисы
Анализ дерева отказов
Анализ дерева отказов работает в обратном направлении от сбоя, используя булеву логику (вентили AND/OR) для определения всех возможных комбинаций причин.
Database Outage
|
AND
/ \
Slow Query No Connection
Exists Pool Recovery
| |
OR AND
/ \ / \
Missing Unoptimized No pool No timeout
index query plan monitoring configured
Когда использовать анализ дерева отказов: Сложные, критически важные для безопасности системы, где нужно понимать все возможные пути отказа. Распространён в авиации, медицинских устройствах и ядерных системах. Менее распространён в веб-приложениях, но ценен для критической инфраструктуры.
Написание отчётов RCA
Шаблон отчёта RCA
# Root Cause Analysis: [Incident Title]
Date: [Date of incident]
Author: [Name]
Severity: [Sev-1 / Sev-2 / Sev-3]
Status: [Draft / In Review / Final]
## Summary
One paragraph: what happened, when, how long it lasted, what was affected.
## Timeline
| Time (UTC) | Event |
|---|---|
| 14:00 | Monitoring alert: database connection pool at 90% |
| 14:05 | On-call engineer acknowledged alert |
| 14:12 | Database connection pool exhausted; application returning 503 |
| 14:15 | Incident declared; war room opened |
| 14:25 | Slow query identified via database monitoring |
| 14:30 | Query killed manually; connections began recovering |
| 14:35 | Application fully recovered |
| 14:40 | Root cause identified: missing index on orders.created_at |
| 14:45 | Index added to production database |
| 15:00 | Monitoring confirmed stable; incident resolved |
## Impact
- Duration: 23 minutes (14:12 - 14:35)
- Users affected: approximately 3,200 (all users attempting checkout)
- Revenue impact: estimated $8,500 in lost transactions
- Support tickets: 47
## Root Cause
The migration that should have added an index to the `orders.created_at`
column failed silently during the v2.3.0 deployment (2 weeks prior).
Without the index, a new report query introduced in v2.4.0 performed a
full table scan on 50 million rows, consuming database connections
for 30+ seconds each.
## Contributing Factors
1. **Migration monitoring gap:** Migration failures log to a file but
do not trigger alerts. The team was unaware of the failed migration.
2. **No query performance testing:** The CI pipeline does not test
query performance against production-scale data volumes.
3. **Staging data mismatch:** Staging has 1,000 rows in the orders
table; production has 50 million. The query performed well in staging.
4. **No connection pool circuit breaker:** When the pool fills, the
application queues requests indefinitely instead of failing fast.
## Corrective Actions
| Action | Owner | Priority | Due Date | Status |
|---|---|---|---|---|
| Add alerting for migration failures | DevOps | P1 | 2026-02-21 | In progress |
| Add query performance tests to CI | QA | P2 | 2026-03-07 | Not started |
| Configure connection pool circuit breaker | Backend | P2 | 2026-03-07 | Not started |
| Create staging data seeding script (production-scale) | QA + DevOps | P3 | 2026-03-21 | Not started |
| Add slow query monitoring dashboard | DevOps | P2 | 2026-02-28 | Not started |
## Lessons Learned
- Silent failures are the most dangerous kind. If something can fail,
the failure must be visible.
- Testing against unrealistic data volumes gives false confidence.
- Connection pool exhaustion cascades: one slow query can take down
the entire application. Defense in depth (circuit breakers,
timeouts, connection limits) is essential.
Безобвинительные пост-мортемы
Язык, фокусирующийся на системах, а не на людях
Единственный наиболее важный принцип безобвинительных пост-мортемов: люди не вызывают инциденты; системы позволяют инцидентам произойти. Когда кто-то совершает ошибку, вопрос не «почему он это сделал?», а «почему система сделала эту ошибку лёгкой для совершения и трудной для обнаружения?»
| Обвинительный язык | Безобвинительный язык |
|---|---|
| «Алиса забыла добавить индекс» | «Миграция, которая должна была добавить индекс, завершилась молча с ошибкой» |
| «Боб задеплоил без тестирования» | «Процесс развёртывания не включал обязательный шаг верификации тестами» |
| «Разработчик написал плохой запрос» | «Запрос не был протестирован на объёмах данных масштаба продакшена» |
| «QA пропустило этот баг» | «Наше тестовое покрытие не включало этот сценарий» |
| «Дежурный инженер медленно отреагировал» | «Маршрутизация алертов не доставила оповещение на телефон дежурного инженера» |
Как вести безобвинительный пост-мортем
- Задайте тон в начале. «Эта встреча посвящена обучению и улучшению, а не назначению виноватых. Мы предполагаем, что все участники принимали лучшие решения, которые могли, с той информацией, которую имели.»
- Фокусируйтесь на хронологии. Пройдите по событиям в хронологическом порядке. Сначала факты, потом анализ.
- Спрашивайте «что» и «как», а не «кто». «Что сделало возможным, чтобы это произошло?», а не «Кто это вызвал?»
- Отмечайте реагирование. Признайте, что прошло хорошо во время реагирования на инцидент, а не только что пошло не так.
- Завершайте действиями, а не оценками. Каждое корректирующее действие должно менять систему или процесс, а не наказывать человека.
Отслеживание корректирующих действий до завершения
Наиболее частый провал в процессе RCA — не сам анализ, а доведение до конца. Команды пишут тщательные отчёты RCA с отличными корректирующими действиями, а затем эти действия лежат в таблице до следующего инцидента.
Система отслеживания
- Создайте тикеты для каждого корректирующего действия в той же системе, где отслеживается работа по разработке (Jira, Linear, GitHub Issues). Если этого нет в бэклоге, это не будет сделано.
- Назначьте владельца и дедлайн. «Команда это исправит» означает, что никто это не исправит.
- Еженедельно проверяйте прогресс на стендапе или на выделенной 15-минутной встрече.
- Закрывайте RCA только когда все действия выполнены (или явно депроиритизированы с задокументированным обоснованием).
Категории корректирующих действий
| Категория | Описание | Пример |
|---|---|---|
| Немедленное исправление | Исправляет конкретную проблему, вызвавшую этот инцидент | Добавить отсутствующий индекс в базе данных |
| Улучшение обнаружения | Делает подобные проблемы видимыми раньше | Добавить алертинг на сбои миграций |
| Предотвращение | Изменяет систему так, чтобы этот класс проблем не мог возникнуть | Добавить тесты производительности запросов в CI |
| Изменение процесса | Обновляет процедуру для предотвращения повторения | Добавить обязательное ревью медленных запросов для новых запросов |
| Документация | Фиксирует знания для будущего справочника | Задокументировать лимиты пула соединений и конфигурацию circuit breaker |
Шаблоны RCA с примерами из практики
Пример 1: Продакшен-сбой (Электронная коммерция)
Инцидент: Поток оформления заказа возвращал ошибки 500 в течение 45 минут во время Black Friday.
Коренная причина: Сторонний API платежей изменил лимит запросов с 1,000 до 500 запросов в минуту без уведомления. Приложение не обрабатывало ограничение скорости корректно.
Корректирующие действия:
- Добавить обработку ограничения скорости с экспоненциальной задержкой
- Реализовать очередь запросов с переливом к альтернативному платёжному провайдеру
- Добавить мониторинг и алертинг по лимитам запросов
- Согласовать контрактные гарантии лимитов запросов с платёжным провайдером
Пример 2: Утечка данных (SaaS-платформа)
Инцидент: Данные клиентов были доступны через API-эндпоинт без аутентификации.
Коренная причина: Новый API-эндпоинт был добавлен без middleware аутентификации. Код-ревью не поймало это, потому что ревьюер не знал о требовании аутентификации для API-маршрутов.
Корректирующие действия:
- Добавить автоматическое сканирование безопасности, отмечающее неаутентифицированные эндпоинты
- Обновить чек-лист код-ревью, включив проверку аутентификации
- Добавить интеграционные тесты, проверяющие, что все API-эндпоинты требуют аутентификации
- Внедрить default-deny: все новые эндпоинты требуют аутентификации, если явно не помечены как публичные
Пример 3: Деградация производительности (Мобильное приложение)
Инцидент: Время запуска приложения деградировало с 2 до 8 секунд за период 3 недели.
Коренная причина: Был добавлен новый SDK аналитики, который выполнял синхронные сетевые вызовы при инициализации приложения. Регрессия производительности была постепенной (добавлена в 3 PR) и оказалась ниже порога любого отдельного теста производительности.
Корректирующие действия:
- Добавить бюджет производительности времени запуска в CI (падение, если запуск превышает 3 секунды)
- Требовать асинхронную инициализацию для всех сторонних SDK
- Добавить мониторинг тренда производительности, обнаруживающий постепенную деградацию
- Провести аудит всех существующих инициализаций SDK на синхронные вызовы
Типичные антипаттерны в RCA
| Антипаттерн | Проблема | Лучший подход |
|---|---|---|
| Остановка на первом «почему» | Исправляется симптом; коренная причина остаётся | Продолжайте спрашивать, пока не дойдёте до системной причины |
| Перекладывание вины | «API вендора был плохим» — уход от вопроса, почему у вас не было резервного плана | Спросите, почему ваша система была хрупкой к сбою вендора |
| Исправление симптомов, а не причин | Добавление временного исправления без устранения причины его необходимости | Исправьте и непосредственную проблему, и системную причину |
| Паралич анализа | Недели на RCA, пока корректирующие действия ждут | Ограничьте анализ по времени; внедрите очевидные исправления немедленно |
| Копипаст RCA | Использование одного и того же типового шаблона без адаптации к инциденту | Каждый RCA должен быть конкретным, детальным и действенным |
| Отсутствие доведения до конца | Написание отличного RCA и неисполнение действий | Отслеживайте действия в бэклоге спринта с владельцами и датами |
| Героизация | «Алиса спасла нас, найдя исправление в 3 ночи» нормализует героизм | Спросите, почему система потребовала героизма вместо изящной обработки |
Превращение RCA в действия: от анализа к предотвращению
Мерило хорошего RCA — не качество анализа. Это то, прекратил ли такой же тип инцидентов происходить.
Иерархия предотвращения
- Устранить: Полностью убрать возможность сбоя (лучший вариант, но часто невозможный)
- Автоматизировать обнаружение: Поймать проблему до попадания в продакшен (проверки в CI, автоматические сканы)
- Ограничить зону поражения: Если сбой произойдёт, ограничить его влияние (circuit breakers, feature flags, канареечные развёртывания)
- Ускорить восстановление: Упростить обнаружение и быстрое восстановление после сбоя (мониторинг, runbooks, автоматический откат)
- Задокументировать: Как минимум, задокументировать сбой, чтобы будущие команды могли его распознать (худший вариант, но лучше, чем ничего)
Всегда стремитесь к наивысшему возможному уровню. Если вы можете только задокументировать, ваш RCA не зашёл достаточно далеко.
Практическое упражнение
- Возьмите недавний продакшен-инцидент и напишите полный отчёт RCA, используя шаблон выше
- Потренируйте технику «5 Почему» на недавнем баге. Вы дошли до системной коренной причины или остановились на симптоме?
- Просмотрите прошлый RCA вашей команды. Реализованы ли корректирующие действия? Если нет, почему?
- Перепишите прошлый отчёт об инциденте, убрав любой обвинительный язык, используя примеры безобвинительного языка
- Создайте диаграмму рыбьей кости для сложного инцидента, категоризируя причины по 6 М