Введение
После выпуска изменение становится частью живой системы. Его поведение зависит от реальных данных, нагрузки, конфигурации и зависимостей. Успешный deployment ещё не позволяет судить о результате для пользователя.
Модуль рассматривает ответственность инженерного лида за систему в эксплуатации. Центральный вопрос — как команда понимает, работает ли пользовательская функция, и что позволяет ей действовать, когда эта функция нарушена.
1. Живая система как отдельный объект ответственности
Исходный код и живая система — не один объект.
Исходный код можно прочитать. Живая система существует одновременно в нескольких слоях:
- исполняющийся код;
- конфигурация;
- инфраструктура;
- состояние данных;
- очереди и потоки событий;
- внешние зависимости;
- реальные пользователи;
- реальная нагрузка;
- сетевые задержки и частичные отказы;
- версии клиентов;
- процессы deployment и rollback;
- действия операторов;
- накопленная история предыдущих изменений.
Один и тот же commit может:
- работать в staging, но падать на production data;
- работать в одном регионе и ломаться в другом;
- возвращать HTTP 200, но создавать неправильное состояние;
- быть корректным сам по себе, но нарушать старый контракт клиента;
- выдерживать 10 RPS и разрушаться при 1 000 RPS.
Поэтому формула «код прошёл тесты» не завершает рассуждение. Она сообщает только об одном классе наблюдений в одной среде.
Ответственность за production не равна личному всемогуществу
Лид не обязан один чинить базу, Kubernetes, сеть, Kafka, frontend и внешнего провайдера. Его ответственность в другом:
- границы владения определены;
- сигналы существуют;
- alert имеет адресата;
- эскалация возможна;
- runbook доступен;
- изменения обратимы настолько, насколько это возможно;
- решение о риске принято явно;
- после сбоя система получает изменение, а не только объяснение.
2. Пользовательская функция как центр наблюдения
Состояние системы нужно оценивать по тому, может ли пользователь выполнить нужное действие и получить правильный результат. Нормальный CPU, работающий сервер и отсутствие alerts сами по себе этого не подтверждают.
Инфраструктурные показатели — CPU, memory, disk, connection pool и consumer lag — помогают объяснять отклонения и заранее замечать приближение к пределу. Для проверки пользовательской функции нужны отдельные сигналы.
Пользовательская функция в разных системах
| Система | Пользовательская функция | Возможные показатели |
|---|---|---|
| Интернет-магазин | Покупатель оформляет заказ | Доля успешно завершённых checkout, latency, корректность суммы |
| Платёжный сервис | Платёж получает конечный корректный статус | Success ratio, time to final state, duplicate charge rate |
| Поиск | Пользователь получает релевантный ответ | Availability, latency, empty-result anomalies, correctness proxies |
| Хранилище | Данные можно записать и потом прочитать без потери | Write success, read success, durability, consistency |
| Очередь | Принятое сообщение будет обработано в допустимое время | Publish success, consumer lag, end-to-end processing latency |
| Отчётный pipeline | Данные появляются полностью и вовремя | Freshness, completeness, correctness, processing deadline |
| Authentication | Пользователь получает доступ согласно политике | Login success, latency, false denial, false authorization |
Техническое здоровье и функциональное здоровье
В платёжном сценарии pods работают, CPU составляет 35%, memory — 60%, а доля HTTP 2xx — 99,99%. При этом событие подтверждения оплаты не публикуется, заказ остаётся в статусе Pending: деньги списаны, но пользователь не видит завершённого заказа.
Показатель пользовательского сценария обнаружит нарушение, а технические сигналы помогут локализовать его причину.
3. Telemetry, monitoring и observability
Эти понятия часто используют как синонимы, хотя они обозначают разные слои.
Telemetry
Telemetry — данные, которые система производит о собственном выполнении:
- logs;
- metrics;
- traces;
- profiles;
- events.
OpenTelemetry определяет traces как путь запроса через приложение, metrics как измерения во время выполнения, logs как записи событий, а baggage как контекст, передаваемый между сигналами и процессами. (OpenTelemetry Signals)
Monitoring
Monitoring — контур сбора и проверки показателей, для которых команда заранее определила нормальные значения, способ отображения и отклонения, требующие действия.
Google SRE различает white-box monitoring внутренних показателей системы и black-box monitoring внешнего поведения, видимого пользователю. (Google SRE: Monitoring Distributed Systems)
Observability
Observability в практическом смысле — способность исследовать внутреннее состояние живой системы по производимым ею сигналам, в том числе задавать вопросы, которые не были полностью известны до инцидента.
Monitoring позволяет проверить заранее известное условие. Observability помогает исследовать неожиданное отклонение: например, выяснить, что произошло с определённым классом запросов в конкретном регионе после изменения и на какой зависимости возникла проблема.
Само наличие logs, metrics и traces не даёт этой способности. Для расследования их нужно связывать с конкретным запросом, версией системы и пользовательским результатом.
4. Logging: журнал решений живой системы
Лог нужен, чтобы восстановить значимое событие: какая операция выполнялась, что произошло с состоянием и почему система приняла решение.
Выбор событий
Записи entered method, calling repository и left method показывают ход выполнения кода, но не объясняют изменение в системе. Запись order state transition rejected: current=SHIPPED, requested=CANCELLED, policy=immutable_after_shipping уже сообщает, какой переход отклонён и какое правило сработало.
Даже сообщение о важной ошибке бесполезно без контекста. По строке Error processing request нельзя установить, какой запрос завершился ошибкой, изменилось ли состояние и можно ли безопасно повторить операцию.
Контракт логирования
Команда определяет, какие поля обязательны для каждого класса событий и что они означают. Общая часть записи связывает событие с запросом и версией сервиса, а поля конкретной операции позволяют восстановить её результат. Контракт должен охватывать:
- время, сервис, среду и версию;
- операцию, итог и длительность;
- идентификаторы запроса и trace для связи с другими сигналами;
- безопасные идентификаторы сущностей и значимые изменения состояния;
- категорию ошибки, возможность повтора и причину решения, когда они нужны для расследования;
- уровень записи в соответствии с последствиями события.
Пример записи о тайм-ауте при подтверждении платежа:
{
"timestamp": "...",
"severity": "ERROR",
"service": "payment-orchestrator",
"environment": "production",
"version": "2026.07.21-4f82a1",
"trace_id": "8ec2...",
"span_id": "31ad...",
"request_id": "req-7421",
"operation": "confirm_payment",
"event": "payment_confirmation_timed_out",
"provider": "acme-pay",
"payment_state_before": "AUTHORIZED",
"outcome": "UNKNOWN",
"retry_policy": "CHECK_PROVIDER_STATUS_BEFORE_RETRY",
"error_code": "PROVIDER_TIMEOUT",
"duration_ms": 2503,
"message": "Provider confirmation timed out"
}
Уровень записи
Поле severity помогает отделить обычные события от отклонений и отказов. Команда должна согласовать смысл каждого уровня:
| Уровень | Что означает |
|---|---|
| DEBUG | Детали исследования, обычно отключаемые или сохраняемые выборочно |
| INFO | Нормальное значимое событие жизненного цикла |
| WARN | Отклонение, которое система обработала, но которое может потребовать анализа |
| ERROR | Операция не достигла ожидаемого результата |
| FATAL | Процесс или критическая подсистема не может продолжать работу |
Если каждое исключение логируется как ERROR, включая ожидаемую бизнес-валидацию, этот уровень перестаёт означать отказ.
Безопасность и данные
Нельзя автоматически писать в logs:
- пароли;
- access tokens;
- session cookies;
- полные номера банковских карт;
- секреты;
- чувствительные персональные данные;
- необработанные request/response bodies без явного основания.
Логи должны помогать расследованию без раскрытия секретов и лишних персональных данных. (OWASP: Logging Cheat Sheet)
Retention, sampling и стоимость
Лид должен знать:
- сколько данных производит сервис;
- сколько стоит хранение и поиск;
- какие logs нужны для оперативного расследования;
- какие нужны для аудита;
- какие можно сохранять выборочно;
- какой retention требуется юридически и технически;
- что произойдёт с telemetry pipeline при всплеске ошибок.
Если retry записывает одну и ту же ошибку при каждой попытке, один пользовательский сбой превращается в тысячи строк. При массовом отказе такой поток может переполнить диск или observability backend и усилить исходный инцидент.
5. Metrics: видеть состояние системы во времени
Metrics агрегируют поведение системы и позволяют видеть частоту, распределение, изменение и приближение к пределам.
Основные формы
Для измерения поведения сервиса используют, в частности, counter, gauge и histogram. (Prometheus: Metric types)
| Форма | Что показывает | Пример |
|---|---|---|
| Counter | Количество событий, которое накапливается со временем | requests_total, payments_failed_total |
| Gauge | Текущее значение, которое может расти и уменьшаться | queue_depth, active_connections |
| Histogram | Распределение наблюдений по диапазонам | request_duration_seconds |
Four Golden Signals
Google SRE выделяет четыре базовых сигнала для наблюдения за системой. Они дают стартовую карту, но не заменяют показатели выполнения пользовательской функции. (Google SRE: Monitoring Distributed Systems)
Traffic
Traffic — нагрузка, которую пользователи или другие системы создают для сервиса. Её измеряют в единицах, соответствующих функции сервиса:
- для HTTP API — число запросов в секунду, отдельно по операциям;
- для очереди сообщений — число поступающих сообщений в секунду;
- для пакетной обработки — число заданий или объём входящих данных за час;
- для сервиса с длительными соединениями — число активных сессий.
Объём нагрузки нужен для интерпретации других показателей. Пять ошибок из десяти запросов и пять из десяти миллионов означают разные доли отказов.
Latency
Latency — время выполнения операции в заданных границах. Для HTTP-запроса серверная задержка начинается при получении запроса сервером и заканчивается отправкой ответа. Задержка, измеренная клиентом, включает передачу по сети. Время всего checkout может заканчиваться только тогда, когда заказ получил конечный статус, а не когда отдельный сервис вернул ответ.
Даже для одной операции запросы выполняются с разной скоростью, и среднее время ответа может скрывать медленные запросы. Чтобы увидеть их, определяют границу времени, в которую уложилась заданная доля запросов за выбранный период. Эту границу называют перцентилем и обозначают pN, где N — доля запросов в процентах. Например, если для успешных запросов checkout API p95 = 800 мс, то 95% запросов завершились за 800 мс или быстрее, а остальные — медленнее. (Google SRE: Service Level Objectives)
Показатели считают отдельно для разных операций и для успешных и неуспешных запросов. Иначе быстрый ответ 500 может снизить среднюю задержку как раз во время отказа. (Google SRE: Monitoring Distributed Systems)
Errors
Для errors измеряют долю операций, которые не достигли ожидаемого результата за выбранный период. Критерий неуспеха зависит от функции системы. (Google SRE: Monitoring Distributed Systems)
Примеры показателей:
- доля запросов с HTTP 5xx или timeout среди всех запросов API;
- доля попыток оформления, после которых заказ не создан, даже если API вернул HTTP 200;
- доля отчётов, в которых сумма не сошлась при проверке с исходными данными;
- доля задач, завершённых после установленного предельного времени.
Saturation
Saturation показывает, насколько близок к пределу ресурс, который может ограничить работу сервиса. Для разных ресурсов измеряют разные величины:
- CPU — долю используемого лимита и время, в течение которого срабатывает throttling;
- память — рабочий объём процесса относительно доступного лимита;
- пул соединений — число занятых соединений из общего числа и время ожидания свободного соединения;
- очередь — число ожидающих элементов и время ожидания старейшего;
- обработчик сообщений — отставание от входящего потока в сообщениях или секундах;
- внешний API — оставшуюся квоту запросов до обновления лимита.
Почти заполненный пул соединений показывает, что запас ёмкости мал. Если при этом запросы всё дольше ждут свободного соединения и растёт время выполнения пользовательской операции, пул, вероятно, ограничивает обработку.
Число временных рядов (cardinality)
Одна метрика может состоять из нескольких временных рядов: например, отдельно для каждого региона и класса ответа. Число этих рядов называют cardinality метрики.
Разбивку задают labels — поля метрики, например region="eu" и status_class="5xx". Каждое уникальное сочетание их значений создаёт отдельный ряд: три значения region и четыре значения status_class дают до 12 рядов одной метрики. (Prometheus: Metric and label naming)
Для разбивки подходят labels с ограниченным числом значений, например region, operation, status_class и provider. Labels user_id, request_id, raw_url и order_id могут принимать почти уникальное значение для каждого запроса и быстро умножают число рядов. Это повышает нагрузку и стоимость monitoring backend. Идентификатор отдельного запроса обычно нужен в logs и traces, а не в metrics.
6. Tracing: причинный путь запроса
Метрики показывают, что задержка checkout выросла, но не объясняют, на каком этапе конкретного оформления заказа ушло время. Trace связывает этапы одной операции, даже если они выполняются в разных сервисах. Он помогает увидеть, сколько заняли резервирование товара, авторизация платежа и вызов внешнего провайдера. (OpenTelemetry Traces)
Из чего состоит trace
| Элемент | Что показывает |
|---|---|
| Trace | Связанные этапы одной операции с общим trace_id |
| Span | Отдельный этап работы с временем начала и окончания, например вызов платёжного провайдера |
| Связь parent–child | Какой этап вызвал следующий; дочерний span может выполняться в другом сервисе |
| Attributes | Поля этапа, например код ответа или имя внешнего сервиса |
| Events | События внутри этапа, например начало повторной попытки |
| Status | Отметка о том, завершился ли этап с ошибкой |
В trace оформления заказа входящий запрос может быть родительским span для резервирования товара и авторизации платежа. Вызов провайдера будет дочерним span авторизации. По времени и связям между ними можно проверить, где возникла задержка или ошибка; это особенно полезно при длинных цепочках вызовов и повторных попытках. (OpenTelemetry Traces)
Передача контекста между этапами
Чтобы этапы попали в один trace, следующий сервис должен получить контекст предыдущего, прежде всего trace_id и идентификатор родительского span. При HTTP-вызове его можно передать в заголовках, при обработке сообщения — в метаданных сообщения. Та же связь нужна при запуске фоновой работы. Если контекст теряется после отправки сообщения в очередь, trace показывает отправку, но не обработку сообщения. (OpenTelemetry: Context propagation)
Baggage позволяет передавать вместе с контекстом дополнительные пары ключ–значение. Эти данные могут пройти через несколько сервисов и попасть к внешнему получателю, поэтому секреты и персональные данные в baggage помещать нельзя. (OpenTelemetry: Context propagation)
Выборка traces
При большом потоке сохранять каждый trace дорого. Выборка (sampling) сокращает объём данных, но вместе с отброшенными traces можно потерять редкие ошибки и медленные операции.
При head sampling решение принимают в начале операции: это экономит ресурсы, но её итог ещё неизвестен. При tail sampling решение принимают после получения большей части этапов trace: так можно сохранить traces с ошибками или высокой задержкой, однако для этого нужно временно удерживать данные в памяти. Правила выборки стоит проверять по тому, остаются ли доступными traces критических операций и сбоев. (OpenTelemetry: Sampling)
7. Correlation: связать сигналы с изменениями
Допустим, после 14:03 выросла доля неуспешных оформлений заказа. Метрика показывает масштаб и время отклонения. По времени, операции и региону можно найти отдельные попытки в logs и traces. trace_id связывает запись о конкретной попытке с её этапами. (OpenTelemetry: Log correlation) Версия сервиса и отметка о deployment позволяют проверить, совпало ли отклонение с изменением системы. Совпадение по времени даёт гипотезу, которую ещё нужно проверить.
Какие данные связывают сигналы
| Переход | Что нужно сохранить |
|---|---|
| От метрики к отдельным попыткам | Время, операция, сервис, среда и при необходимости регион; одинаковый смысл этих полей во всех сигналах |
| От записи в логе к trace | trace_id и, для конкретного этапа, span_id |
| От отклонения к изменению | Время и место deployment, service.version в logs и traces |
| От ошибки к затронутой сущности | Безопасный идентификатор заказа или другой сущности в logs и traces |
Часы источников должны быть согласованы: иначе события разных сервисов трудно расположить на одной временной шкале. Идентификаторы отдельных запросов и заказов не следует добавлять в labels метрик: они создают слишком много временных рядов. (Prometheus: Metric and label naming)
Изменение под feature flag
Если новая логика включена для 10% пользователей, общего показателя успешности checkout недостаточно. Нужно считать долю успешных оформлений отдельно для попыток с прежним и новым вариантом, сохраняя для каждого варианта число успешных попыток и число всех попыток. В logs и traces вариант помогает проверить конкретный случай.
Для сравнения достаточно добавить вариант нужного флага к показателям затронутой операции. Если добавлять все флаги ко всем метрикам, число сочетаний labels и временных рядов быстро вырастет. (Prometheus: Metric and label naming)
8. Health checks: жив, готов и реально работает — разные состояния
Health check помогает автоматике принять решение о конкретном экземпляре сервиса. В Kubernetes для этого есть три вида probes с разными последствиями. (Kubernetes Probes)
| Проверка | На какой вопрос отвечает | Что происходит при устойчивом отказе |
|---|---|---|
| Startup | Завершило ли приложение запуск? | Контейнер перезапускается; до успешной проверки liveness и readiness не выполняются |
| Liveness | Нужно ли перезапустить контейнер, чтобы восстановить его работу? | Контейнер перезапускается |
| Readiness | Можно ли сейчас направлять запросы на этот экземпляр? | Pod перестаёт получать трафик через соответствующие Service |
Проверка должна соответствовать действию
Liveness должна выявлять состояние, при котором перезапуск действительно помогает, например зависание процесса. Если она проверяет общую внешнюю базу, её краткий сбой может одновременно перезапустить все экземпляры приложения и усилить отказ. (Kubernetes Probes)
Readiness подходит для состояния конкретного экземпляра: например, он ещё прогревает кэш и не готов принимать запросы. Если же проверка опрашивает общую для всех базу и при её отказе убирает из трафика все экземпляры, обслуживать запросы станет некому. Проверяя зависимость, нужно понимать, поможет ли исключение именно этого экземпляра из маршрутизации. (Kubernetes Probes)
Что health check не доказывает
Ответ 200 OK от /health может означать лишь то, что приложение ответило на простой запрос. Он не подтверждает, что пользователь смог оформить заказ. Но и проверка, которая при каждом вызове синхронно обходит все зависимости, может создавать лишнюю нагрузку и сама ухудшать состояние системы.
Успешность пользовательского сценария, деградацию сервиса и необходимость вызвать дежурного определяют по отдельным сигналам и правилам реакции. Результат probe сам по себе не заменяет такого наблюдения.
9. Dashboards: карта принятия решений
Dashboard собирает заранее выбранные показатели, чтобы при отклонении быстро оценить воздействие на пользователей и выбрать направление проверки. На одном экране не нужно показывать всё, что система умеет измерять. Google SRE рекомендует строить обзор вокруг основных вопросов о состоянии сервиса и его ключевых сигналов. (Google SRE: Monitoring Distributed Systems)
Обзор сервиса
| Вопрос | Что показать |
|---|---|
| Затронуты ли пользователи? | Долю успешных операций относительно принятой цели и задержку ключевых сценариев |
| Каков масштаб и когда началось? | Число операций, динамику ошибок и разбивку по операциям и регионам |
| Что могло измениться? | Время развёртываний и изменения конфигурации рядом с показателями; при необходимости — версии затронутых экземпляров |
| Где искать ограничение? | Очереди, занятость пулов и другие показатели насыщения зависимостей |
| Кто может действовать? | Текущий инцидент, дежурного и ссылки на инструкции по восстановлению |
Путь пользователя
Обзор каждого сервиса по отдельности не показывает, завершился ли сквозной сценарий. Для оформления заказа можно отслеживать, сколько попыток дошло от начала checkout до авторизации платежа, подтверждения заказа и доставки подтверждения. Переходы нужно считать для одной и той же группы попыток с учётом допустимого времени между этапами: иначе ещё выполняющиеся заказы будут выглядеть как потерянные.
Если платёж авторизован, а заказ не подтверждён в ожидаемый срок, такой dashboard покажет место разрыва, даже когда локальные показатели сервисов остаются нормальными.
Dashboard нужен для оценки состояния и расследования. Отклонение, требующее срочного действия, должно вызвать оповещение: команда не может полагаться на постоянное наблюдение за экраном. (Google SRE: Monitoring Distributed Systems)
10. Alerts: когда система имеет право прервать человека
Метрика показывает состояние системы. Правило оповещения решает, нужно ли человеку действовать и насколько быстро. Канал должен соответствовать срочности действия. (Google SRE: Monitoring Distributed Systems)
Срочность и канал
| Канал | Когда использовать | Действие получателя |
|---|---|---|
| Page | Пользователи уже затронуты или серьёзное воздействие близко, а ждать рабочего времени нельзя | Немедленно начать проверку и смягчение воздействия |
| Ticket | Проблему нужно исправить, но она может ждать рабочего времени | Назначить владельца и срок работы |
| Информационное сообщение | Изменение полезно знать, но действия не требуется | Прочитать при необходимости; не направлять на pager |
Page должен сообщать, что нарушено, кого это затрагивает, насколько срочно действие и кто отвечает за него. В нём нужны ссылка на dashboard, инструкция для первого шага и данные о недавних изменениях, если они помогают расследованию.
Когда будить по симптому или причине
Для page обычно выбирают наблюдаемое воздействие на пользовательскую функцию. Например, доля успешно завершённых checkout устойчиво падает при достаточном числе попыток. Одно значение CPU выше 80% такого воздействия ещё не показывает: оно полезно на dashboard и может стать основанием для плановой работы с ёмкостью. (Google SRE: Monitoring Distributed Systems)
По внутренней причине будят раньше, если она надёжно предсказывает близкий отказ и есть конкретное срочное действие. Например, диск с журналом транзакций базы может заполниться раньше, чем команда успеет освободить место или переключить запись. Порог такого page нужно связать со временем до исчерпания ресурса и временем реакции, а не с произвольным процентом заполнения. (Google SRE: Monitoring Distributed Systems)
Шум оповещений и пересмотр правил
Если pages регулярно закрываются сами, дублируют друг друга или не требуют действия, дежурный привыкает их игнорировать. Такой шум может скрыть настоящее нарушение. Google SRE поэтому рассматривает каждый page как дорогое прерывание. (Google SRE: Monitoring Distributed Systems)
При пересмотре правила команда проверяет, было ли воздействие или близкая угроза, требовалось ли срочное действие, помогло ли сообщение найти первый шаг и был ли доступен актуальный runbook. Если нет, правило меняют: уточняют условие и окно наблюдения, переводят проблему в ticket или устраняют дублирование. Повторяющееся механическое действие стоит автоматизировать.
11. SLI, SLO и SLA
Фактически предоставленный уровень сервиса, целевой уровень и обязательство перед пользователем — разные вещи. Для них используют SLI, SLO и SLA. (Google SRE: Service Level Objectives)
SLI — измеряемый показатель
SLI (Service Level Indicator) — количественная мера одного аспекта работы сервиса. Для пользовательских операций её часто выражают долей: число хороших событий делят на число всех учитываемых событий. При этом нужно заранее определить и «хорошее», и то, какие события входят в знаменатель. (Google SRE: Service Level Objectives; Google SRE Workbook: Implementing SLOs)
| Сценарий | Хорошее событие | Что входит в знаменатель |
|---|---|---|
| Доступность API | Допустимый запрос получил ожидаемый ответ | Все допустимые запросы |
| Оформление заказа | Корректный заказ создан не позднее двух секунд после начала checkout | Все допустимые попытки checkout |
| Публикация отчёта | Отчёт опубликован до 08:00 | Все ожидаемые отчёты |
Допустимость события задаётся обязательством сервиса, а не желаемым результатом измерения. Заведомо некорректный запрос можно исключить, если сервис не обещал его выполнить. Но timeout из-за внешней зависимости остаётся в знаменателе, если пользователь ожидал результата от этой операции.
SLO — целевой уровень
SLO (Service Level Objective) задаёт целевое значение или диапазон для SLI. (Google SRE: Service Level Objectives)
Чтобы цель можно было проверить, фиксируют границу операции и класс пользователей, критерии хорошего и учитываемого события, точку измерения, окно и целевое значение. Также определяют, что делать с отсутствующими данными: пропуск измерения нельзя автоматически считать успешной операцией.
Например, для показателя оформления заказа из таблицы можно задать такую цель: за последние 28 дней не менее 99,9% допустимых попыток checkout завершаются созданием корректного заказа не позднее двух секунд после начала попытки.
SLA — обязательство с последствиями
SLA (Service Level Agreement) — договорённость с пользователем или заказчиком, в которой указано, что произойдёт при нарушении согласованного уровня сервиса. Договорным последствием может быть, например, компенсация или право расторгнуть договор. Если соглашение не устанавливает последствий нарушения, перед нами, как правило, SLO, а не SLA. (Google SRE: Service Level Objectives)
Почему не стоит автоматически выбирать 100%
Для доли успешных операций цель в 100% означает, что любой сбой за окно измерения нарушит её. Поддержание такой цели может потребовать непропорциональных затрат и ограничить изменения системы. Уровень выбирают по потребности пользователей и цене отказа, а допустимый объём отклонений рассматривают в следующем разделе как error budget. (Google SRE: Service Level Objectives)
12. Error budget: допустимая граница ненадёжности
Error budget — допустимый объём невыполнения SLO за его окно. Если цель для checkout составляет 99,9% успешных попыток, на неуспешные приходится 0,1% всех учитываемых попыток: 100% − 99,9% = 0,1%. Это граница для управления риском, а не цель обязательно допустить сбои. (Google SRE Workbook: Implementing SLOs)
Единица бюджета зависит от того, как задан SLI:
| SLI | Бюджет при цели 99,9% за 28 дней |
|---|---|
| Доля успешных операций | 0,1% учитываемых операций; если их было 10 000 000, допустимо до 10 000 неуспешных |
| Доля времени доступности | 0,1% времени; за 28 дней это 40,32 минуты недоступности |
Число допустимых неуспешных операций зависит от фактического объёма работы. Временной бюджет относится к другому SLI: минуты недоступности нельзя напрямую приравнять к числу неуспешных запросов.
Скорость расхода бюджета
Burn rate показывает, насколько быстро расходуется бюджет по сравнению с допустимой скоростью. Для SLO, заданного долей успешных операций, его считают как долю неуспешных операций за выбранный интервал, делённую на допустимую долю неуспеха. Значение 1 соответствует допустимой скорости; 10 — расходу в десять раз быстрее. (Google SRE Workbook: Alerting on SLOs)
При SLO 99,9% наблюдаемая доля ошибок 1% даёт burn rate 10, потому что 1% / 0,1% = 10. Если такая доля сохраняется при постоянном потоке операций, за 2,8 дня будет израсходован объём бюджета, рассчитанный на 28 дней. Это оценка скорости, а не обещание точной даты исчерпания бюджета.
Оповещения по нескольким окнам
Одно короткое окно быстро замечает резкий рост ошибок, но отдельный всплеск может создать шум. Длинное окно показывает значимый расход бюджета, но после восстановления ещё долго содержит прежние ошибки. Поэтому для одного условия оповещения проверяют оба окна: длинное подтверждает масштаб расхода, короткое — что ошибки продолжаются сейчас. Для быстрого и медленного расхода задают разные пороги и каналы реакции. (Google SRE Workbook: Alerting on SLOs)
При малом числе операций доля ошибок сильно меняется от одного события. Тогда правило оповещения нужно проверять с учётом объёма трафика, иначе единичный отказ может вызвать несоразмерный page. (Google SRE Workbook: Alerting on SLOs)
Правила действий при расходе бюджета
Политика error budget заранее определяет:
- какой расход бюджета и за какое время требует решения;
- кто следит за бюджетом и принимает решение;
- какие изменения ограничиваются и при каком условии их можно возобновить;
- какие работы по надёжности получают приоритет;
- какие исключения возможны и кто их согласует;
- как разрешают разногласия и когда пересматривают политику.
Её согласуют продуктовая команда, разработка и эксплуатация; иначе численное значение бюджета не превращается в общее правило действий. При достижении согласованного порога команда применяет предусмотренные политикой меры и пересматривает приоритеты. (Google SRE Workbook: Implementing SLOs)
Например, за восемь дней потрачено 70% бюджета на 28 дней, главным образом из-за тайм-аутов нового пути платежа. Если согласованная политика требует действий при таком расходе, команда может остановить расширение rollout и сначала устранить тайм-ауты. Бюджет показывает масштаб риска, а конкретное решение следует из политики и обстоятельств.
13. On-call: право системы вызвать человека
On-call — порядок, при котором назначенный инженер в оговорённое время получает срочный page, отвечает на него и начинает восстановление сервиса или привлекает нужных людей. Для этого заранее определяют время реакции, путь эскалации и условия работы дежурного. (Google SRE: Being On-Call)
Что нужно до начала дежурств
Команда проверяет:
- кто владеет сервисом, какие ситуации попадают к дежурному и за какое время он должен ответить;
- работает ли доставка page и известен ли путь эскалации;
- доступны ли dashboards, runbooks и проверенные способы смягчения воздействия, включая rollback;
- кому сообщать о проблеме зависимости и когда объявлять incident;
- прошёл ли новый участник обучение и дежурство вместе с опытным инженером.
Основной и резервный дежурный
Расписание должно показывать, кто сейчас выполняет каждую роль:
- основной дежурный принимает page, оценивает воздействие и начинает реакцию;
- резервный подхватывает вызов, если основной недоступен, либо помогает с диагностикой и эскалацией.
Распределение задач зависит от команды: резерв может быть инженером той же ротации или соседней команды. Важно заранее проверить, что вызов до него доходит и у него есть доступ к нужному контексту. (Google SRE: Being On-Call)
Полномочия для реакции
Дежурному нужен согласованный способ быстро:
- остановить развёртывание или начать откат, если изменение усиливает сбой;
- отключить проблемную функцию или переключить трафик, если система допускает эти действия;
- привлечь владельца зависимости и объявить incident;
- получить необходимые права по заранее проверенной процедуре аварийного доступа (break-glass).
Если действие требует отдельного согласования, владелец решения и способ связи с ним должны быть известны заранее. Иначе время реакции зависит от поиска человека, который разрешит следующий шаг.
Передача смены
Новый дежурный должен получить состояние, которое ещё может потребовать действий:
- открытые инциденты и текущую деградацию с владельцами и следующим шагом;
- развёртывания, миграции и feature flags в нестандартном состоянии;
- временно отключённые alerts и способ заметить соответствующий сбой;
- известные ограничения ёмкости, проблемы зависимостей и ожидаемые внешние события.
Устойчивость ротации
Команда отслеживает число инцидентов и вызовов за смену, ночные прерывания и время, которое остаётся на разбор и устранение повторяющихся проблем. (Google SRE: Being On-Call)
Если нагрузка постоянно мешает восстановлению и последующей работе, меняют конкретную причину: правила оповещений, повторяющийся отказ, ручную операцию или устройство смен. Также нужно предусмотреть подмену дежурного и восстановление после тяжёлой ночной смены.
14. Что такое incident
Incident — незапланированное состояние, которое уже нарушает или существенно угрожает нарушить ожидаемую функцию сервиса и требует координированной реакции.
Не каждый bug — incident. Не каждый alert — incident. И incident может существовать до того, как root cause известен.
Основания объявить incident
- нарушен критический пользовательский сценарий;
- быстро расходуется error budget;
- существует риск потери или повреждения данных;
- нарушена безопасность;
- затронут значимый сегмент пользователей;
- несколько команд уже расследуют одну проблему;
- требуется координация изменений и коммуникации.
Объявить рано дешевле, чем поздно
Formal incident mode можно отменить. Потерянное в неструктурированном хаосе время вернуть нельзя.
Google SRE Workbook приводит случаи, где позднее объявление incident приводило к несогласованной реакции и более долгому восстановлению. (Google SRE Workbook: Incident Response)
Пример severity model
Названия уровней организация определяет сама, но критерии должны опираться на impact.
| Severity | Пример воздействия | Режим |
|---|---|---|
| SEV-0 | Угроза безопасности людей, критическая потеря данных, полный системный кризис | Немедленная максимальная эскалация и executive coordination |
| SEV-1 | Критический сценарий массово недоступен, существенный финансовый или договорный риск | Incident command, page всех нужных владельцев, регулярные updates |
| SEV-2 | Частичная деградация, значимый сегмент затронут, workaround ограничен | Координированная реакция и контролируемая коммуникация |
| SEV-3 | Ограниченное воздействие, устойчивый workaround, нет быстрого роста | Владелец, ticket, исправление в рабочем режиме |
Severity может повышаться и понижаться по мере появления фактов.
15. Incident response: сначала вернуть функцию
Цель активного incident response — ограничить воздействие на пользователей и восстановить функцию сервиса. Расследование помогает выбрать действие, но безопасную меру для снижения воздействия не откладывают до доказательства причины. (Google SRE Workbook: Incident Response)
Ход реакции
- Обнаружить и оценить. Проверить, какая пользовательская функция нарушена, кого это затронуло и продолжает ли расти воздействие.
- Объявить инцидент и организовать работу. Зафиксировать уровень серьёзности, назначить ответственных за действия и коммуникацию. Уровень и состав участников уточняют по мере появления фактов.
- Ограничить воздействие (mitigation). Остановить новые отказы или уменьшить их масштаб: например, остановить rollout, отключить проблемный путь или переключить трафик.
- Восстановить функцию (recovery). Вернуть пользователю возможность получить правильный результат и обработать последствия сбоя, если они остались в данных или очередях.
- Проверить и завершить активную фазу (resolution). Убедиться по пользовательским сценариям и состоянию данных, что воздействие прекратилось и восстановление устойчиво. Оставшиеся риски и работы передать конкретным владельцам.
Одна мера может одновременно ограничить воздействие и восстановить часть функции. Например, после выпуска нового платёжного пути оплаченные заказы остаются в статусе Pending. Отключение этого пути и возврат на прежний прекращают появление новых зависших заказов и позволяют оформлять новые. Но уже зависшие заказы ещё нужно довести до корректного состояния. Нормальный график ошибок сам по себе не подтверждает завершения восстановления.
Действие до выяснения причины
Если выпуск совпал с началом сбоя, это повод проверить изменение, а не доказательство его вины. Когда откат безопасен и способен уменьшить воздействие, его можно выполнить, по возможности сохранив данные для расследования. Причины затем разбирают по фактам; во время активного воздействия расследование не должно задерживать восстановление функции.
После завершения инцидента команда разбирает причины; при выполнении установленных критериев проводит postmortem. Корректирующие действия (corrective actions) снижают вероятность или последствия повторения. Исправление исходного дефекта может быть одной из таких задач: закрытие активной фазы не означает, что вся последующая работа уже выполнена.
16. Роли внутри incident response
Первым на инцидент обычно реагирует дежурный. Он может сам оценивать воздействие, восстанавливать сервис и сообщать о происходящем. Когда задач становится слишком много для одного человека, он подключает других и передаёт им часть обязанностей. Роли помогают явно разделить координацию, техническое восстановление и коммуникацию; они не требуют отдельного человека на каждую задачу с самого начала. Google SRE выделяет Incident Commander, Operations Lead и Communications Lead как основные роли. (Google SRE Workbook: Incident Response)
Incident Commander
Incident Commander (IC) отвечает за ход инцидента в целом:
- определяет текущий приоритет и назначает ответственных за техническую работу и коммуникацию;
- согласует действия разных групп, когда они конфликтуют или несут дополнительный риск;
- уточняет уровень серьёзности и запрашивает эскалацию, когда имеющихся полномочий или людей недостаточно;
- завершает активную фазу после проверки восстановления и передачи оставшихся задач владельцам.
IC не обязан быть главным экспертом по неисправному компоненту. Если он сам ведёт каждое расследование и одновременно пишет исправление, координация остаётся без владельца.
Operations Lead
Operations Lead (OL) ведёт техническую реакцию:
- распределяет направления расследования и собирает подтверждённые наблюдения;
- предлагает меры для ограничения воздействия и восстановления функции;
- координирует изменения в production, чтобы действия исполнителей не мешали друг другу;
- проверяет результат по пользовательскому сценарию и состоянию данных.
Communications Lead
Communications Lead (CL) отвечает за сообщения участникам инцидента и заинтересованным сторонам:
- собирает у технической группы подтверждённые факты, текущие действия и неизвестные обстоятельства;
- выпускает регулярные обновления для команды, поддержки и стейкхолдеров, а при необходимости — для пользователей через согласованные каналы;
- принимает запросы на информацию, чтобы они не прерывали техническую работу каждого участника.
Scribe
Scribe фиксирует ход инцидента: когда обнаружили симптомы, какие гипотезы проверяли, какие решения приняли, кто и что сделал и каким был результат. Отдельного человека для этой роли назначают, когда поток событий уже трудно удерживать вместе с другой работой.
Наблюдение, гипотезу и подтверждённую причину отмечают раздельно. Иначе запись может превратить раннюю догадку в «факт» для последующих участников и postmortem.
Журнал решений
Журнал позволяет восстановить, почему команда выбрала действие и как проверила его результат. В нём достаточно фиксировать время, решение, основание, исполнителя и проверку:
| Время | Решение и основание | Исполнитель | Проверка |
|---|---|---|---|
| 14:07 | Прекратить расширение rollout при охвате 25%: среди заказов на новом платёжном пути выросла доля Pending. |
OL | Rollout остановлен на текущем охвате. |
| 14:11 | Включить обработчик сообщений нового формата, затем отключить флаг: новый путь уже записал такие сообщения. | OL | Новые заказы проходят через прежний путь; ранее записанные сообщения обрабатываются. |
Журнал нужен для координации во время инцидента и последующего разбора, а не для поиска виновного.
17. Коммуникация во время инцидента
Во время инцидента участникам и заинтересованным сторонам нужно понимать, что происходит с пользовательской функцией, какие меры приняты и когда появится следующая информация. Если обновлений нет, люди начинают выяснять статус у каждого исполнителя отдельно; если гипотезы выдаются за факты, дальнейшие решения опираются на неверную картину.
Обновление статуса
В сообщении указывают воздействие и время его начала, подтверждённые действия и их результат, оставшуюся неизвестность, следующий шаг и время следующего обновления. Технические детали добавляют для тех, кому они нужны для работы; сообщение пользователям строят вокруг воздействия и восстановления. (Google SRE Workbook: Incident Response)
INC-2026-042 · SEV-1. С 13:54 около 32% заказов после авторизации платежа остаются в статусе
Pending.Новый платёжный путь отключён для новых заказов; прежний путь работает. Полный объём заказов, требующих восстановления, пока неизвестен. Следующий шаг — сверить их с платежами и восстановить корректные статусы.
Следующее обновление — в 14:40 или раньше, если состояние существенно изменится.
Факт, гипотеза и решение
Внутри команды полезно явно обозначать статус каждого утверждения. Рост числа заказов в Pending после выпуска — наблюдение. Предположение, что новый producer не публикует событие подтверждения, — гипотеза. Остановить rollout — решение, которое можно принять до проверки гипотезы, если продолжение выпуска увеличивает воздействие.
В обновлении нельзя превращать временное совпадение выпуска и сбоя в установленную причину. Если причина ещё неизвестна, так и пишут, сохраняя точность в описании воздействия и действий.
Регулярность обновлений
Время следующего сообщения назначают заранее и соблюдают, даже если причина ещё не найдена. В таком обновлении можно сообщить, сохраняется ли воздействие, что уже проверено, что команда проверяет сейчас и когда вернётся с новой информацией. При существенном изменении состояния сообщение отправляют раньше.
18. Rollback и roll-forward
Rollback возвращает прежнюю версию приложения или конфигурации. Roll-forward выпускает исправление поверх текущей версии. Во время инцидента выбирают действие, которое быстрее и с меньшим дополнительным риском восстановит пользовательскую функцию.
Вопросы перед выбором
- Какой вариант быстрее уменьшит воздействие на пользователей?
- Какой путь команде лучше известен: откат или выпуск исправления?
- Совместима ли прежняя версия с текущими данными и контрактами?
- Можно ли остановить расширение rollout, временно ограничить или перенаправить трафик?
- Что произойдёт с операциями, которые уже выполняются (in-flight)?
- Доступен ли артефакт предыдущей версии или конфигурации для отката?
- Проверялся ли откат на практике?
- Можно ли сначала выключить feature flag, чтобы новые запросы снова обрабатывались прежним способом?
Когда откатывать
Откат разумен, если сбой начался после изменения, прежняя версия совместима с текущими данными и сообщениями, а сам откат проверен и доступен. Совпадение по времени не доказывает причину, но для безопасного отката не обязательно сначала её установить: во время активного воздействия приоритет — восстановление сервиса. (Google SRE: Service Best Practices)
Когда выпускать исправление
Roll-forward может быть безопаснее, если прежняя версия уже не умеет работать с записанными данными или контрактом клиентов, возвращает другую критическую неисправность либо откат займёт больше времени, чем понятное и проверенное исправление. Срочный патч сам по себе не безопаснее отката: нужно оценить, что изменится для пользователей и как проверить результат.
Совместимость данных и контрактов
Откат приложения не возвращает автоматически прежнее состояние данных. Например, если новая версия записала сообщения в формате, который старый обработчик не понимает, возврат старого кода не обработает накопившуюся очередь и может усилить сбой. Тогда для восстановления нужен другой путь.
Возможность rollback нужно проектировать до deployment: обеспечить совместимость версий с записанными данными и сообщениями, а также проверить, что произойдёт с операциями, начатыми до переключения. Во время инцидента поздно обнаруживать, что предыдущая версия не умеет читать новую запись.
При изменении схемы данных или контракта сохранить такую совместимость на время rollout помогает подход expand → migrate → contract:
- Expand: добавить новую структуру, не удаляя старую, чтобы прежняя версия продолжала работать.
- Migrate: перенести данные и постепенно переключить чтение и запись; пока возможен откат, обе версии должны работать с состоянием системы.
- Contract: удалить старую структуру после проверки новой и завершения периода, в котором может понадобиться откат.
Так изменение контракта не закрывает путь назад в момент выпуска. После этапа contract возврат прежней версии может стать невозможным; это ограничение учитывают в плане восстановления. (GitLab: Backwards compatibility across updates)
Проверка восстановления
Успешная команда rollback или завершённый выпуск патча ещё не доказывают, что сервис восстановлен. Проверяют пользовательский сценарий, корректность данных и обработку операций, начатых до переключения; затем наблюдают, не возобновляется ли воздействие. Если остались зависшие заказы или сообщения, их восстановление входит в работу по инциденту, даже когда новые запросы уже проходят успешно.
19. Feature flags и progressive delivery
Feature flag — управляемое во время работы приложения условие: оно позволяет изменить поведение без нового развёртывания кода. (OpenFeature) Флаг полезен при выпуске, если новую функцию можно включить для части пользователей, наблюдать за результатом и при необходимости быстро выключить.
Deployment и release
Deployment означает, что код развёрнут в production. Release означает, что новое поведение стало доступно пользователям. Код может быть уже развёрнут, а функция ещё выключена флагом: тогда её включение и расширение аудитории не требуют нового deployment.
Что дают flags
- Проверить новое поведение в production сначала на сотрудниках или ограниченном сегменте пользователей.
- Постепенно расширять аудиторию нового поведения и сравнивать его результат с прежним вариантом.
- Проводить A/B-эксперимент, если цель — сравнить варианты продукта, а не только проверить безопасность выпуска.
- Выключить проблемную функцию или обращение к зависимому сервису без нового deployment, если предусмотрено безопасное поведение при выключении. Такой флаг может служить kill switch.
Чтобы флаг ограничивал воздействие сбоя, нужны ограниченная аудитория, сигналы по обоим вариантам и проверенная возможность переключения.
Жизненный цикл флага
Флаг добавляет в систему ещё одно изменяемое состояние. Чтобы им можно было управлять во время выпуска и инцидента, для него фиксируют:
- имя, назначение и владельца;
- значение по умолчанию и поведение при недоступности системы управления флагами;
- кто может менять значение и где сохраняется история изменений;
- план расширения аудитории и условие остановки или обратного переключения;
- показатели и dashboard, по которым проверяют результат;
- условие и ответственного за удаление флага после завершения выпуска.
Долг от оставленных флагов
Оставленный после выпуска флаг сохраняет обе ветки поведения и усложняет проверку изменений. Три независимых булевых флага дают до восьми комбинаций, десять — до 1 024. Не все сочетания обязательно достижимы, но забытые ветки и правила включения увеличивают объём проверки и затрудняют расследование. Поэтому временный флаг удаляют вместе с больше не нужной веткой кода, когда решение о выпуске принято.
Проверка kill switch
Выключение флага может остановить новые обращения к проблемному пути, но не отменяет уже выполненные операции и изменения данных. Надёжному переключению могут помешать:
- изменение значения применяется с неприемлемой задержкой;
- при недоступности системы управления флагами SDK не может получить безопасное значение;
- значение по умолчанию включает проблемное поведение;
- поведение после выключения несовместимо с уже записанными данными;
- у дежурного нет права переключить флаг.
Флаг проверяют заранее: переключают в рабочей среде или на реалистичном испытании и убеждаются, что нужное поведение действительно прекращается за ожидаемое время. Изменение значения также должно оставлять запись о том, кто и когда его выполнил: без неё сложнее восстановить ход инцидента.
Постепенный выпуск
Progressive delivery — выпуск, при котором аудиторию нового поведения или новой версии расширяют поэтапно, опираясь на результаты наблюдения. Его можно проводить через флаг для доли пользователей или через развёртывание на части экземпляров. Например, после проверки на сотрудниках новое поведение включают для 1% пользователей, затем для 5%, 25%, 50% и всей аудитории. Размер шага и время наблюдения выбирают так, чтобы успеть увидеть эффект до расширения воздействия.
Перед следующим шагом сравнивают новый и прежний варианты на сопоставимых операциях. Проверяют:
- не ухудшился ли SLI затронутой пользовательской операции в новом варианте;
- остаётся ли допустимой скорость расхода error budget;
- нет ли нарушений целостности данных;
- не приближаются ли ресурсы к пределу насыщения;
- не появились ли обращения в поддержку с новым классом проблем.
Проверку нового поведения или новой версии на ограниченной доле пользователей либо экземпляров называют canary. Она ограничивает воздействие размером группы и временем наблюдения; переход к следующему этапу зависит от результатов проверки, а не только от прошедшего времени. (Google SRE Workbook: Canarying Releases)
20. Graceful degradation и ограничение blast radius
При частичном отказе или перегрузке задача — сохранить самые важные пользовательские операции. Blast radius — масштаб воздействия: какие операции, группы пользователей и части системы затронуты. Его ограничивают, заранее определяя, что можно временно упростить, изолировать или отклонить ради сохранения основной функции.
Graceful degradation
Graceful degradation — заранее предусмотренное поведение, при котором сервис сохраняет важную для пользователя операцию с ограниченным качеством или набором возможностей. Например:
- При недоступности сервиса рекомендаций каталог показывает популярные товары из заранее подготовленного списка.
- При перегрузке обработки изображений сервис отдаёт уже подготовленный вариант вместо создания нового.
- При задержке аналитического конвейера оформление заказа продолжается, а аналитическое событие обрабатывается позже.
Упрощённый результат должен оставаться корректным для своей задачи: например, устаревшую цену нельзя выдавать за актуальную. Путь деградации проверяют заранее, иначе во время перегрузки он может оказаться таким же недоступным, как основной. (Google SRE: Service Best Practices)
Bulkheads
Bulkhead — разделение ресурсов или нагрузки на изолированные части. Если один класс операций зависает или исчерпывает свой лимит, остальные сохраняют выделенную им ёмкость. Разделять можно:
- пулы потоков и очереди для разных классов операций;
- лимиты запросов и ресурсы разных клиентов (tenants);
- регионы или другие области отказа (failure domains), если между ними нет общей точки перегрузки.
Например, запросы к медленному сервису рекомендаций не должны занимать все потоки, нужные для оформления заказа. Разделение помогает только при реальной изоляции: общий исчерпанный пул соединений снова свяжет судьбу обеих операций. (Microsoft: Bulkhead pattern)
Circuit breaker
Если зависимость отвечает ошибками или зависает, новые вызовы продолжают расходовать ресурсы обеих сторон. Circuit breaker отслеживает сбои и после заданного порога временно прекращает обращения к зависимости: вызывающий сервис быстро возвращает ошибку или предусмотренный упрощённый результат. Затем он пропускает ограниченное число пробных вызовов, чтобы проверить восстановление зависимости. (Microsoft: Circuit Breaker pattern)
Такой механизм не заменяет обработку ошибки в пользовательской операции. Для критической зависимости нужно заранее определить, допустим ли упрощённый результат или операцию следует честно отклонить.
Retry budget
Повтор может помочь при кратковременном сбое, но при перегрузке он добавляет запросы к уже страдающей зависимости. Если три последовательных слоя независимо делают до трёх попыток, один исходный запрос может породить до 27 обращений к нижнему слою. (AWS: Timeouts, retries, and backoff with jitter)
Чтобы повторы не усиливали отказ, задают:
- тайм-аут и общий предел времени для операции;
- какие ошибки допускают повтор и сколько попыток разрешено;
- экспоненциальную паузу с разбросом (jitter), чтобы клиенты не повторяли запрос одновременно;
- идемпотентность операции или ключ идемпотентности, если повтор может создать второй результат;
- общий retry budget — предел суммарного потока повторов, а не только попыток одного запроса.
Общий предел времени ограничивает повторы одного пользовательского запроса, а retry budget — суммарный поток повторов от многих запросов. Без этих ограничений при массовом сбое повторные вызовы могут занять ресурсы, нужные для восстановления.
Load shedding
Load shedding — управляемый отказ от части входящей работы, когда доступной ёмкости недостаточно даже для упрощённого ответа. Например, сервис временно отклоняет запросы на рекомендации, чтобы сохранить обработку заказов, вместо того чтобы держать обе операции в растущей очереди до тайм-аута. (Google SRE: Handling Overload)
Приоритеты операций, порог включения ограничения и способ его снять определяют до перегрузки. Иначе система может отклонить именно ту работу, ради сохранения которой вводили ограничение.
21. Postmortem: восстановить причинность после сбоя
Postmortem — письменный разбор инцидента: что произошло с пользовательской функцией, как развивались сбой и реакция на него, какие условия сделали его возможным и что следует изменить. Разбор завершается проверяемыми действиями, а не только описанием событий. (Google SRE: Postmortem Culture)
Когда нужен postmortem
Критерии разбора задают до инцидента, чтобы решение не зависело от того, насколько тяжёлым он кажется после восстановления. Основанием может быть:
- превышение установленного порога серьёзности или заметный расход error budget;
- потеря либо повреждение данных;
- воздействие на безопасность;
- восстановление дольше установленного порога;
- событие, которое случайно не привело к более тяжёлым последствиям;
- повторение известного класса отказа;
- обнаружение системного пробела, важного для других команд.
Порог, например по длительности или воздействию на пользователей, должен быть записан в правилах команды. Разбор можно провести и вне этих критериев, если инцидент выявил важный способ отказа. (Google SRE: Postmortem Culture)
Структура
Разбор связывает воздействие, последовательность событий, условия отказа и последующие изменения. В документе фиксируют:
- Краткое описание (Summary): что произошло.
- Воздействие (Impact): кого затронуло, как именно и на какое время.
- Обнаружение (Detection): как узнали о сбое и почему не раньше.
- Хронологию (Timeline): наблюдения, решения, действия и их результат.
- Технический ход событий (Technical narrative): как развивался отказ в системе.
- Сопутствующие условия (Contributing factors): что сделало сбой возможным или усилило его.
- Что помогло (What went well): какие действия и защитные механизмы ограничили воздействие или ускорили восстановление.
- Что помешало (What went poorly): что задержало обнаружение, ограничение воздействия или восстановление.
- Где повезло (Where we got lucky): что могло ухудшить исход, но не ухудшило по случайным причинам.
- Последующие действия (Action items): что изменить, кто отвечает, каков приоритет и как проверить результат.
Воздействие на пользователей
Фраза «Kafka consumer был недоступен 47 минут» описывает состояние компонента, но не показывает воздействие на пользователей. В разборе нужно указать затронутую операцию, масштаб и длительность. Например: «В течение 47 минут 18 420 оплаченных заказов не получили подтверждение; 3 120 пользователей повторили попытку, для 84 платежей потребовалась ручная сверка». Если точное число пока неизвестно, приводят оценку и отмечают её неопределённость.
Хронология событий
Хронологию восстанавливают по журналу решений, телеметрии и сообщениям участников. Для значимых событий указывают:
- время события и источник отметки времени;
- что наблюдали в этот момент;
- какое решение приняли и на основании каких данных;
- какое действие выполнили;
- что изменилось после действия.
Если время приблизительное, это указывают. Позднюю реконструкцию и предположение о причине отделяют от того, что участники действительно наблюдали во время инцидента.
Action items
Фраза «Быть внимательнее при изменении Kafka» не задаёт изменения системы и не позволяет проверить результат. Если сбой был связан с доставкой события оплаты, последующее действие можно описать так:
- Изменение: добавить тест доставки события оплаты через конфигурацию Kafka, эквивалентную production, с проверкой чтения действующим consumer.
- Владелец: команда Payments Platform.
- Приоритет: P1.
- Проверка: тест падает на прежней конфигурации и проходит на исправленной.
Такие действия становятся задачами с владельцами и приоритетами. Их выполнение отслеживают, а результат проверяют по указанному критерию. (Google SRE Workbook: Postmortem Culture)
22. Blameless culture: анализ причин и ответственность
Blameless postmortem описывает действия людей как часть хода инцидента, но не подменяет анализ причин оценкой личности. Нужно понять, какой информацией человек располагал, почему решение могло выглядеть допустимым и какие условия системы позволили действию привести к сбою. Это даёт основания изменить систему и способ работы с ней. (Google SRE: Postmortem Culture)
Что принцип не отменяет
Blameless разбор сохраняет возможность:
- проверять, на чём основывалось решение и какие у него были последствия;
- фиксировать отступление от процедуры, не скрывая его и не объявляя объяснением всех причин;
- оценивать, был ли риск согласованным и соответствовал ли известным ограничениям;
- разбирать повторяющиеся действия и проверять, почему прежние изменения не предотвратили повторение;
- назначать владельцев последующих действий и проверять их выполнение;
- отличать добросовестную ошибку от умышленного нарушения.
Ответственность сохраняется
Участник инцидента отвечает за:
- точное описание своих действий и доступного ему на тот момент контекста;
- участие в разборе и проверке его выводов;
- выполнение взятых последующих действий;
- применение согласованных изменений в дальнейшей работе.
Лид отвечает за:
- разбор решений без публичного поиска виновного;
- анализ технических и организационных условий, а не только последнего действия человека;
- приоритизацию последующих изменений и устранение организационных препятствий;
- проверку, что согласованные изменения выполнены и дали ожидаемый результат.
Где проходит граница
Добросовестная ошибка, решение при неполной информации, сознательное принятие согласованного риска, повторяющееся игнорирование известного ограничения и умышленное нарушение — разные ситуации. Их нельзя заранее объяснить одной формулой «человеческая ошибка». Если есть признаки умышленного действия или систематического игнорирования требований, это рассматривают отдельно; postmortem при этом всё равно должен объяснить, почему действие смогло повлиять на систему и пользователей.
Например, запись «Инженер запустил скрипт» фиксирует действие, но не объясняет масштаб последствий. Для разбора нужно спросить:
- почему по умолчанию включался режим массового изменения или удаления данных;
- почему признаки среды не позволяли отличить production от staging;
- почему не было предварительного просмотра действий (dry-run);
- почему права доступа позволяли массовое действие;
- почему система не запросила подтверждение масштаба действия;
- почему не удалось быстро восстановить данные из резервной копии;
- почему оповещение пришло после жалоб пользователей.
23. Root Cause Analysis: от триггера к последствиям
Root Cause Analysis (RCA) восстанавливает, как событие и существовавшие условия вместе привели к пользовательскому воздействию. Один триггер редко объясняет масштаб и длительность сложного инцидента: разные факторы могли сделать сбой возможным, усилить его или задержать восстановление. Выводы опираются на наблюдения, а недоказанные связи остаются гипотезами. (Google SRE: Effective Troubleshooting)
При разборе полезно различать:
- Триггер (trigger): событие, запустившее проявление сбоя.
- Скрытое условие (latent condition): существовавшая до события уязвимость системы или процесса.
- Сопутствующие факторы (contributing factors): условия, которые увеличили вероятность или масштаб сбоя.
- Механизм распространения (propagation mechanism): как локальный отказ затронул другие операции или компоненты.
- Пробел обнаружения (detection gap): почему воздействие не заметили раньше.
- Пробел реакции (response gap): что задержало ограничение воздействия или восстановление.
- Фактор восстановления (recovery factor): что помогло вернуть функцию или ограничить последствия.
Пробелы обнаружения и реакции объясняют длительность воздействия; фактор восстановления показывает, что сработало. Их не следует выдавать за причину, запустившую сбой.
Пример
В условном примере после развёртывания новой конфигурации отправителя сообщений оплаченные заказы стали оставаться в статусе Pending: событие подтверждения оплаты не доходило до обработчика. Причинную картину можно изложить по тем же частям:
- Триггер: развёртывание новой конфигурации отправителя событий.
- Скрытое условие: Kafka broker в staging принимал оба протокола безопасности, а в production требовалось конкретное значение
security.protocol; поэтому проверка в staging не выявила ошибку. - Сопутствующие факторы: схема конфигурации проверяла тип параметра, но не допустимые значения; подтверждение заказа после асинхронной обработки не входило в критерии выпуска.
- Распространение: повторные попытки публикации увеличивали очередь отклонённых сообщений.
- Обнаружение: canary проверял успешность HTTP-ответа, но не конечный статус заказа; SLI по времени перехода заказа в конечный статус не было.
- Реакция: runbook не описывал, как безопасно отключить новый путь после появления сообщений нового формата.
- Восстановление: сохранённый прежний путь и feature flag позволили остановить новые сбои после включения обработчика сообщений нового формата.
В реальном разборе каждую такую связь проверяют по конфигурации, сообщениям, метрикам и хронологии инцидента.
5 Whys
Метод 5 Whys помогает продолжить вопрос «почему?» после ближайшего объяснения. (Google SRE: Effective Troubleshooting) Запись «инженер указал неправильный параметр» может быть фактом, но не показывает, почему значение было допустимо и как ошибка дошла до пользователей. Действие человека здесь служит началом анализа.
В сложном инциденте вопросы расходятся по нескольким ветвям:
- Путь изменения: почему параметр принимал опасное значение, схема не проверяла его, а review не располагал нужным контекстом?
- Путь данных: какие сообщения были записаны или отклонены и что с ними произошло после переключения?
- Распространение: почему воздействие вышло за пределы первого сбоя и blast radius оказался большим?
- Обнаружение: почему canary не увидел эффект на конечном статусе заказа?
- Реакция: почему восстановление зависело от ручного действия и нужная последовательность не была описана в runbook?
- Организационные условия: где в процессе выпуска были закреплены проверка совместимости конфигураций и контроль асинхронного результата?
Одна цепочка «почему» может пропустить независимый фактор. Несколько ветвей помогают найти изменения, которые предотвращают сбой, раньше показывают его воздействие или сокращают восстановление. (Google SRE: Effective Troubleshooting)
Совпадение по времени не доказывает причину
Последний deployment — повод проверить изменение, но в тот же момент могли измениться трафик, значение feature flag, сертификат, поведение зависимости или распределение данных. Вывод о причине требует связи между конкретным изменением, механизмом отказа и наблюдаемым воздействием; при недостатке данных его обозначают как вероятный, а не установленный. (Google SRE: Effective Troubleshooting)
Подозрительный выпуск можно откатить, чтобы уменьшить воздействие, до окончательного вывода о причине. Успешное восстановление после отката помогает проверить гипотезу, но само по себе ещё не доказывает, что все остальные факторы исключены.
24. Operational readiness
Operational readiness — подтверждённая способность команды поддерживать пользовательскую функцию после выпуска: замечать отклонения, ограничивать воздействие, восстанавливать корректное состояние и безопасно менять систему. Работающий deployment ещё не показывает, что команда справится с перегрузкой, отказом зависимости или ошибочным изменением.
Google SRE проводит Production Readiness Review (PRR), прежде чем SRE-команда принимает ответственность за эксплуатацию сервиса. Проверка охватывает архитектуру и зависимости, наблюдаемость, реакцию на сбои, ёмкость, управление изменениями и показатели работы. Состав вопросов уточняют под конкретную систему и её риски. (Google SRE: Production Readiness Review)
Области проверки
Такая проверка связывает уже разобранные в модуле меры с конкретным сервисом. В каждой области важно установить риск и получить подтверждение, что команда сможет действовать:
- Ответственность и полномочия: известны владельцы сервиса и зависимостей, основной и резервный дежурные, путь эскалации; получение обычного и аварийного доступа проверено.
- Контракт сервиса: названы пользователи, критические операции, условия деградации, SLI и SLO, классы трафика и ограничения. По этим определениям можно проверить, работает ли пользовательская функция.
- Архитектура и зависимости: схема соответствует работающей системе; для критических зависимостей понятно поведение при замедлении и отказе, действие тайм-аутов, повторов и ограничений, а также граница распространения сбоя.
- Ёмкость и перегрузка: испытание или модель показывают предел нагрузки, поведение масштабирования и ожидаемый всплеск при запуске; заранее определено, что упростить или какую нагрузку отклонить при насыщении.
- Данные: восстановление из копии проверено, миграции совместимы с прежней версией или имеют план восстановления, критические состояния можно сверить. При необходимости заданы допустимая потеря данных по времени (RPO), время восстановления (RTO), правила хранения и защиты данных.
- Наблюдаемость: метрики, логи и трассировки позволяют увидеть сбой критической операции и связать его с версией или изменением флага; dashboard показывает состояние сервиса и выполнение SLO, а логи не раскрывают секреты.
- Оповещения и дежурство: каждый срочный сигнал ведёт к действию, владельцу и инструкции; тестовое срабатывание проверяет доставку и возможность реакции, а нагрузка на дежурных не скрывает важные сигналы среди шума.
- Безопасность выпуска: выпуск можно расширять по этапам или остановить по заданным условиям; проверены безопасные значения флагов и откат с учётом совместимости данных и уже начатых операций.
- Реакция на инцидент: определены основания объявления, уровни серьёзности, роли, каналы и порядок внутренней и внешней коммуникации; учение проверяет, что будущие дежурные могут ими воспользоваться.
- Runbooks: инструкции доступны дежурным, опасные действия и условия их остановки обозначены, команды проверены, а у документа есть владелец и дата последней проверки.
Глубина проверки зависит от риска сервиса: для одного критична потеря записей, для другого — доступность чтения при пике трафика. Ответ «это предусмотрено» слабее демонстрации работающего механизма: восстановленной копии, испытания нагрузки, сработавшего оповещения или выполненного отката. Google SRE описывает launch checklist как средство систематически находить пропущенные условия и соотносить глубину проверки с риском запуска. (Google SRE: Reliable Product Launches)
Решение по итогам проверки
Результат проверки — список найденных рисков, подтверждений, владельцев и условий выпуска. Команда отделяет то, что нужно исправить до расширения выпуска, от того, что можно принять временно с ограничением трафика, наблюдением и планом устранения. Если критический сценарий нельзя обнаружить или восстановить, это условие запуска, а не пункт, который можно считать выполненным по обещанию.
25. Runbook и playbook
Во время инцидента дежурному нужны инструкции для конкретного действия и общий порядок расследования и координации. В этом модуле runbook описывает проверенную процедуру с определённым результатом, а playbook — работу с классом инцидентов, когда точная причина ещё может быть неизвестна.
Runbook
Runbook ведёт к конкретному результату: например, остановить выпуск неисправного платёжного пути и восстановить подтверждение заказов. Он должен быть доступен из оповещения и указывать, когда процедура применима, какие данные проверить до действия, что делать при отклонении от ожидаемого хода и по каким признакам подтверждать восстановление. (AWS Well-Architected: Runbooks)
При оповещении PaymentConfirmationDelayed недостаточно команды «увеличить число обработчиков»: подтверждения могут задерживаться из-за перегрузки обработчика или из-за того, что отправитель не публикует сообщения. Поэтому инструкция сначала направляет к пользовательскому показателю, отклонённым сообщениям, состоянию очереди и последним изменениям, а затем предлагает действие с явным условием применения. После него проверяют конечный статус заказов и сохранность платежей, а не только размер очереди.
Playbook
Playbook задаёт ход работы для класса инцидентов: что выяснить, как оценить воздействие, кому передать решения и как организовать коммуникацию. Когда выясняется конкретный сбой, он может направить команду к соответствующему runbook. (AWS Well-Architected: Playbooks) Для такого документа полезно фиксировать:
- условия объявления инцидента и уровень серьёзности;
- роли, владельцев направлений работы и каналы связи;
- первые вопросы для оценки воздействия и направления расследования;
- частоту обновлений и контрольные точки решений;
- условия подключения других команд, включая специалистов по безопасности или юридическим вопросам;
- критерии восстановления и завершения активной фазы.
Условие, действие и проверка
Инструкция уменьшает число решений под стрессом, если каждый её шаг показывает не только действие, но и границы его применения:
- цель и признак, по которому шаг нужен;
- предварительные условия, доступы и возможное воздействие;
- команду или действие;
- ожидаемый результат и способ его проверить;
- способ остановить или отменить действие либо ограничить последствия, если отмена невозможна.
Если наблюдения не совпадают с условиями инструкции, дежурный останавливается и эскалирует вопрос вместо механического выполнения следующего шага. Runbook и playbook проверяют с участием человека, который не писал их, и обновляют после изменений системы и разбора инцидентов. (AWS Well-Architected: Runbooks)
26. Метрики incident management
Метрики инцидентов помогают понять, сколько длилось воздействие на пользователей и на каком этапе команда теряла время. Для этого в хронологии фиксируют начало воздействия, первый сигнал, принятие сигнала дежурным, снижение воздействия и подтверждённое восстановление. Закрытие записи об инциденте может произойти позже восстановления и не должно автоматически считаться его моментом.
Что измеряют временные показатели
Для одного инцидента сначала измеряют интервалы между событиями. Среднее по нескольким инцидентам обозначают аббревиатурами; в этом модуле для них приняты следующие границы:
- MTTD (mean time to detect) — среднее время от начала воздействия до обнаружения его командой. Если сбой сначала заметили пользователи, это часть истории обнаружения, а не повод передвинуть начало интервала к первому alert.
- MTTA (mean time to acknowledge) — среднее время от уведомления дежурного до подтверждения, что он принял сигнал и начинает разбор. Быстрое подтверждение само по себе не означает, что воздействие уменьшилось.
- MTTM (mean time to mitigate) — среднее время от начала воздействия до момента, когда его удалось заметно снизить по явно указанному критерию. Например, переключение трафика вернуло работу большинству пользователей, но часть операций ещё требует восстановления.
- MTTR (mean time to recover) — среднее время от начала воздействия до подтверждённого восстановления пользовательской функции и необходимого состояния данных. Если под
MTTRпонимают время до закрытия инцидента или ремонта компонента, это уже другой показатель.
Название не заменяет определения событий и состава выборки. Например, PagerDuty отсчитывает свои MTTA и MTTR от создания записи об инциденте, а в исследовании Google SRE время до восстановления отсчитывается от начала воздействия на продукт. Сравнивать такие числа напрямую нельзя. (PagerDuty: Analytics Dashboard; Google SRE: Incident Metrics in SRE)
Среднее и воздействие
Если девять инцидентов длились по пять минут, а один — десять часов, средняя длительность составит 64,5 минуты. Она не описывает ни обычный случай, ни длительный сбой. Медиана покажет пять минут, но скроет десятичасовой случай. При небольшом числе инцидентов перцентили тоже легко переинтерпретировать; для решений нужно видеть отдельные случаи с большим воздействием и условия, при которых они возникли. Google SRE отдельно предупреждает, что средние времена восстановления и смягчения воздействия плохо подходят для оценки изменений и трендов инцидентов. (Google SRE: Incident Metrics in SRE)
Смотреть на процесс полезно с нескольких сторон:
- Воздействие: длительность, число или доля затронутых операций и пользователей за период сбоя, израсходованный error budget. Это показывает масштаб, который одинаковое время восстановления может скрыть.
- Обнаружение и реакция: распределение интервалов до обнаружения, подтверждения, снижения воздействия и восстановления; случаи, когда первыми сообщили пользователи. Разбор таких случаев показывает, где не хватило сигнала, полномочий или готового действия.
- Повторение и обучение: классы повторяющихся сбоев, время выполнения и проверка action items. Закрытый пункт без проверки результата ещё не показывает, что риск снизился.
- Условия работы дежурных: оповещения без срочного действия, частота прерываний и случаи, когда предусмотренный откат не сработал. Они показывают ограничения процесса, которые не видны по одной длительности инцидента.
Метрика не должна ухудшать решение
Если команду наказывают за большой MTTR, она может раньше объявить восстановление, не проверив состояние данных. Если наказывают за число инцидентов, люди начинают реже их объявлять. Показатели нужны для разбора ограничений системы и проверки изменений, поэтому вместе с числами сохраняют определения событий, контекст воздействия и объяснение необычных случаев.
Итоги модуля
Наблюдение за системой становится полезным, когда технические сигналы связаны с выполнением пользовательской функции. SLI и SLO делают ожидание измеримым, метрики, логи и трассировки помогают обнаружить и объяснить отклонение, а правила оповещения связывают его со срочным действием.
Готовность к эксплуатации проверяется возможностью команды действовать при сбое: у неё есть полномочия, согласованные роли, понятный путь эскалации и проверенные способы ограничить воздействие и восстановить работу. Во время инцидента сначала уменьшают вред для пользователей, затем подтверждают восстановление по результату операции и состоянию данных. Коммуникация и фиксация решений помогают координировать эти действия.
После инцидента важно установить не только непосредственный триггер, но и условия, из-за которых сбой затронул пользователей или затянулся. Результатом разбора становятся изменения с владельцами и проверкой эффекта. Показатели управления инцидентами помогают оценить воздействие, обнаружение и восстановление, если их рассматривают вместе с обстоятельствами отдельных сбоев.
Источники
- Google SRE — Service Level Objectives
- Google SRE — Monitoring Distributed Systems
- OpenTelemetry — Signals
- OpenTelemetry — Traces
- Google SRE Workbook — Incident Response
- Google SRE — Being On-Call
- Google SRE Workbook — Implementing SLOs
- Google SRE Workbook — Alerting on SLOs
- OpenFeature — Introduction
- Kubernetes — Liveness, Readiness, and Startup Probes
- Google SRE Workbook — Canarying Releases
- Google SRE — Postmortem Culture
- Google SRE — The Evolving SRE Engagement Model (Production Readiness Review)
- Google SRE — Reliable Product Launches
- Prometheus — Metric and label naming
- OpenTelemetry — Context propagation
- OpenTelemetry — Sampling
- OpenTelemetry — Log correlation
- Google SRE — Service Best Practices
- GitLab — Backwards compatibility across updates
- Microsoft — Bulkhead pattern
- Microsoft — Circuit Breaker pattern
- AWS — Timeouts, retries, and backoff with jitter
- Google SRE — Handling Overload
- Google SRE Workbook — Postmortem Culture
- Google SRE — Effective Troubleshooting
- AWS Well-Architected — Use runbooks to perform procedures
- AWS Well-Architected — Use playbooks to investigate issues
- Google SRE — Incident Metrics in SRE
- PagerDuty — Analytics Dashboard
- Prometheus — Metric types
- OWASP — Logging Cheat Sheet