Философия SRE
Site Reliability Engineering - инженерная дисциплина, которая применяет подходы разработки ПО к задачам эксплуатации. Термин и практика зародились в Google в 2003 году, когда Бен Трейнор Слосс сформулировал подход: “SRE - это то, что получается, когда разработчик берётся за задачи операционной команды”.
Ключевая идея - надёжность является самой важной характеристикой любой системы. Если пользователи не могут пользоваться сервисом, все остальные фичи не имеют значения.
Принципы Google SRE
- Инженерный подход к операциям - не более 50% времени SRE тратит на оперативную работу (toil), остальное на автоматизацию и улучшение систем
- Ошибки - норма, а не исключение. Вопрос не в том, произойдёт ли сбой, а в том, когда он произойдёт и как быстро восстановиться
- Мониторинг не должен требовать человека для интерпретации. Системы должны автоматически обнаруживать проблемы и, по возможности, автоматически их устранять
- Автоматизация обеспечивает консистентность, скорость и документирование процессов лучше, чем ручные действия
- Постепенные изменения снижают риск. Маленькие и частые релизы безопаснее больших и редких
SRE vs DevOps
| Аспект | DevOps | SRE |
|---|---|---|
| Фокус | Культура и практики доставки ПО | Надёжность и операционная эффективность |
| Метрики | Частота деплоев, lead time | SLI/SLO, error budget, MTTR |
| Подход | Философия и набор практик | Конкретная реализация с метриками |
| Операционная работа | Стремление к автоматизации | Явный лимит на toil (50%) |
| Ошибки | Fail fast, learn fast | Error budget как инструмент управления |
SRE и DevOps
SRE можно рассматривать как конкретную реализацию принципов DevOps. DevOps описывает “что” нужно делать, SRE описывает “как” это делать с измеримыми результатами.
SLI - Service Level Indicators
SLI - количественная метрика, отражающая определённый аспект качества обслуживания. Это конкретное измерение, выраженное в процентах или абсолютных значениях.
Типы SLI
Latency - время обработки запроса. Важно разделять latency успешных и неуспешных запросов. Быстрый ответ с ошибкой 500 не является хорошим latency.
# Пример: 95-й перцентиль latency за 5 минут
histogram_quantile(0.95,
rate(http_request_duration_seconds_bucket{job="api"}[5m])
)
Availability - доля успешных запросов от общего числа. Самый фундаментальный SLI.
# Availability за последние 30 дней
sum(rate(http_requests_total{status!~"5.."}[30d]))
/
sum(rate(http_requests_total[30d]))
Throughput - количество запросов, которое система обрабатывает в единицу времени. Важен для понимания нагрузки и планирования ёмкости.
Error rate - процент запросов, завершившихся ошибкой. Обратная сторона availability, но может измеряться для конкретных типов ошибок.
Saturation - степень заполненности ресурса. Процессор на 90% загрузки, диск на 85% заполнен, 95% соединений из пула заняты.
Выбор SLI для разных типов сервисов
| Тип сервиса | Основные SLI | Обоснование |
|---|---|---|
| API / веб-сервис | Availability, latency (p50, p95, p99) | Пользователь ждёт быстрый ответ |
| Хранилище данных | Availability, durability, latency | Данные не должны теряться |
| Пакетная обработка | Throughput, freshness, correctness | Важна скорость и точность обработки |
| Стриминг | Availability, latency, throughput | Непрерывность потока данных |
| Очередь сообщений | Availability, latency, freshness | Сообщения должны доставляться своевременно |
Перцентили вместо средних
Средняя latency скрывает проблемы. При среднем значении 100ms у 1% пользователей latency может быть 10 секунд. Всегда используйте перцентили: p50 для типичного опыта, p95 и p99 для худших случаев.
SLO - Service Level Objectives
SLO - целевое значение для SLI, определяющее допустимый уровень качества. SLO отвечает на вопрос: “Насколько надёжным должен быть наш сервис?”
Определение SLO
Хороший SLO отвечает трём критериям:
- Достижимость - цель реалистична с учётом архитектуры и зависимостей
- Измеримость - можно автоматически и непрерывно измерять
- Значимость - отражает реальный пользовательский опыт
Выбор targets
Стремление к 100% надёжности - антипаттерн. Разница между 99.99% и 100% требует непропорционально больших инвестиций.
| SLO | Допустимый даунтайм в месяц | Допустимый даунтайм в год |
|---|---|---|
| 99% | 7 часов 18 минут | 3 дня 15 часов |
| 99.9% | 43 минуты 50 секунд | 8 часов 46 минут |
| 99.95% | 21 минута 55 секунд | 4 часа 23 минуты |
| 99.99% | 4 минуты 23 секунды | 52 минуты 36 секунд |
| 99.999% | 26 секунд | 5 минут 16 секунд |
SLO документ
service: payment-api
owner: payments-team
last_review: 2026-01-15
review_period: quarterly
slos:
- name: Availability
sli: "Доля HTTP-запросов с кодом < 500"
target: 99.95%
window: 30 days (rolling)
measurement: |
sum(rate(http_requests_total{status!~"5.."}[30d]))
/ sum(rate(http_requests_total[30d]))
- name: Latency (p95)
sli: "95-й перцентиль latency успешных запросов"
target: 300ms
window: 30 days (rolling)
measurement: |
histogram_quantile(0.95,
rate(http_request_duration_seconds_bucket{status!~"5.."}[30d]))
- name: Latency (p99)
sli: "99-й перцентиль latency успешных запросов"
target: 1000ms
window: 30 days (rolling)
exclusions:
- Плановое обслуживание с уведомлением за 48 часов
- Запросы от внутренних health check эндпоинтовПересмотр SLO
SLO не высечены в камне. Пересматривайте их регулярно:
- Ежеквартально - анализ, соответствуют ли текущие SLO пользовательским ожиданиям
- После инцидентов - если SLO не сработал как индикатор проблемы, его нужно скорректировать
- При изменении архитектуры - новые зависимости и компоненты могут повлиять на достижимость целей
- При росте нагрузки - то, что работало на 1000 RPS, может не работать на 10000 RPS
SLA - Service Level Agreements
SLA - юридически обязывающее соглашение между провайдером и клиентом, определяющее последствия нарушения SLO. Главное отличие от SLO - наличие финансовых или правовых последствий.
Соотношение SLI, SLO и SLA
SLI (что измеряем) → SLO (какой уровень обещаем себе) → SLA (что обещаем клиенту)
SLA всегда должен быть менее строгим, чем внутренний SLO. Если внутренний SLO - 99.95%, то SLA может быть 99.9%. Этот зазор создаёт буфер для реагирования до нарушения SLA.
Бизнес-последствия
| Уровень нарушения | Типичные последствия |
|---|---|
| Превышение SLA на 0.01-0.1% | Сервисные кредиты 10-25% |
| Превышение SLA на 0.1-1% | Сервисные кредиты 25-50% |
| Критическое нарушение | Сервисные кредиты до 100%, право на расторжение |
Формулировки SLA
Плохая формулировка: “Сервис будет доступен 99.9% времени”. Непонятно, как измеряется доступность, какое окно, какие исключения.
Хорошая формулировка: “Провайдер обеспечивает доступность API (доля HTTP-запросов с кодом ответа 2xx или 3xx) не менее 99.9% за каждый календарный месяц, измеряемую с шагом 1 минута из пяти географически распределённых точек мониторинга. Плановое обслуживание, анонсированное за 72 часа, исключается из расчёта.”
Error Budgets
Error budget - допустимое количество ошибок за определённый период, вычисленное из SLO. Если SLO availability - 99.95%, то error budget составляет 0.05% за расчётный период.
Вычисление error budget
Error Budget = 1 - SLO target
Пример для 30-дневного окна:
SLO = 99.95%
Error Budget = 0.05%
Общее количество минут = 30 × 24 × 60 = 43200
Допустимый даунтайм = 43200 × 0.0005 = 21.6 минут
Для запросов:
Общее количество запросов за 30 дней = 100 000 000
Error Budget = 100 000 000 × 0.0005 = 50 000 ошибок
Burn rate
Burn rate показывает, как быстро расходуется error budget. Burn rate = 1 означает, что бюджет будет исчерпан точно к концу окна. Burn rate = 2 означает, что бюджет кончится за половину окна.
Burn Rate = (Фактическая частота ошибок) / (Допустимая частота ошибок)
Пример:
SLO = 99.9%, окно 30 дней
Допустимая частота = 0.1%
Фактическая частота за последний час = 0.5%
Burn Rate = 0.5 / 0.1 = 5
Алертинг на основе burn rate:
# Prometheus alerting rules для burn rate
groups:
- name: slo-burn-rate
rules:
# Критический: бюджет кончится за 2 часа
- alert: HighErrorBurnRate
expr: |
(
sum(rate(http_requests_total{status=~"5.."}[1h]))
/ sum(rate(http_requests_total[1h]))
) / 0.001 > 14.4
for: 2m
labels:
severity: critical
annotations:
summary: "Error budget сгорит за 2 часа (burn rate {{ $value }})"
# Предупреждение: бюджет кончится за 3 дня
- alert: MediumErrorBurnRate
expr: |
(
sum(rate(http_requests_total{status=~"5.."}[6h]))
/ sum(rate(http_requests_total[6h]))
) / 0.001 > 6
for: 15m
labels:
severity: warning
annotations:
summary: "Error budget сгорит за 3 дня (burn rate {{ $value }})"Error budget policies
Политика error budget определяет действия команды в зависимости от состояния бюджета.
Бюджет достаточный (более 50% осталось) - команда работает в обычном режиме, выпускает новые фичи, проводит эксперименты.
Бюджет на исходе (10-50% осталось) - повышенное внимание к надёжности, дополнительное ревью рискованных изменений, ограничение экспериментов в продакшне.
Бюджет исчерпан (0% или меньше) - заморозка фич до восстановления бюджета, все инженерные ресурсы направлены на надёжность, обязательный постмортем для определения причин.
Error budget как инструмент диалога
Error budget переводит дискуссию “нам нужна надёжность” vs “нам нужны фичи” в количественную плоскость. Бюджет есть - выпускаем фичи. Бюджета нет - работаем над надёжностью. Это объективный критерий, а не субъективное решение.
Toil
Toil - ручная, повторяющаяся, автоматизируемая, реактивная работа, не несущая долгосрочной ценности. Перезапуск упавшего сервиса вручную - toil. Написание скрипта, который автоматически перезапускает сервис - инженерная работа.
Характеристики toil
Ручная работа - требует вмешательства человека. Автоматизированные процессы не являются toil, даже если они выполняются часто.
Повторяемость - задача выполняется снова и снова. Разовая миграция базы данных не toil.
Автоматизируемость - задача потенциально может быть выполнена машиной. Стратегическое планирование не toil, потому что требует человеческого суждения.
Реактивность - задача инициируется внешним событием, а не проактивным решением инженера.
Линейный рост с нагрузкой - чем больше серверов, пользователей или сервисов, тем больше времени тратится на эту задачу.
Измерение toil
Toil Rate = (Время на toil за период) / (Общее рабочее время за период) × 100%
Целевой показатель: не более 50% рабочего времени
Идеальный показатель: 20-30%
Ведите учёт toil в течение 2-4 недель, фиксируя каждую задачу:
| Задача | Частота | Время | Автоматизируема | Приоритет |
|---|---|---|---|---|
| Перезапуск сервисов | 5 раз/неделю | 15 мин | Да | Высокий |
| Ротация сертификатов | 1 раз/месяц | 2 часа | Да | Средний |
| Ручной деплой hotfix | 3 раза/неделю | 30 мин | Да | Высокий |
| Чистка логов | 1 раз/неделю | 20 мин | Да | Низкий |
| Ответы на тикеты доступа | 10 раз/неделю | 10 мин | Частично | Средний |
Стратегии сокращения toil
- Приоритизация по ROI - сначала автоматизируйте задачи с наибольшим соотношением “частота × время”
- Self-service инструменты - дайте разработчикам возможность самим управлять доступами, создавать окружения, просматривать логи
- Автоматическое восстановление - self-healing системы, которые перезапускаются, масштабируются и переключаются без участия человека
- Устранение корневых причин - не автоматизируйте workaround, устраните причину проблемы
Incident Management
Управление инцидентами - структурированный процесс обнаружения, реагирования и устранения сбоев в продакшне.
Severity levels
| Уровень | Описание | Время реакции | Примеры |
|---|---|---|---|
| SEV1 / Critical | Полная недоступность сервиса для всех пользователей | 5 минут | Падение основной БД, сетевой сбой |
| SEV2 / Major | Значительная деградация для большого числа пользователей | 15 минут | Потеря одного датацентра, ошибки платежей |
| SEV3 / Minor | Частичная деградация для части пользователей | 30 минут | Медленные запросы в одном регионе |
| SEV4 / Low | Минимальное влияние, обходной путь существует | 4 часа | Некритичный сервис недоступен |
Роли при инциденте
Incident Commander (IC) - координирует все действия, принимает решения, управляет коммуникациями. Не занимается техническим решением проблемы. IC отвечает за процесс, а не за код.
Operations Lead - техническое руководство расследованием. Координирует инженеров, которые непосредственно устраняют проблему.
Communications Lead - информирует стейкхолдеров, обновляет страницу статуса, пишет уведомления пользователям.
Scribe - ведёт таймлайн инцидента в реальном времени, фиксирует все действия и решения.
Communication
Регулярные апдейты - даже если ничего не изменилось, обновляйте стейкхолдеров каждые 15-30 минут. Тишина порождает панику.
Шаблон обновления статуса:
[Время] [SEV уровень] [Сервис]
Текущее состояние: краткое описание проблемы
Влияние: на кого и как влияет
Действия: что делается прямо сейчас
Следующий апдейт: через сколько минут
War rooms
War room - выделенный канал коммуникации для инцидента. Может быть физическим или виртуальным.
Правила war room:
- Только участники инцидента присутствуют в канале
- IC модерирует обсуждение
- Все решения озвучиваются и фиксируются
- Посторонние обсуждения запрещены
- Scribe ведёт лог действий
Timeline
Таймлайн инцидента ведётся в реальном времени:
14:23 UTC - Алерт: Error rate на payment-api превысил 5%
14:25 UTC - On-call инженер подтвердил алерт, начал расследование
14:28 UTC - Объявлен инцидент SEV2, назначен IC
14:32 UTC - Определена причина: OOM на 3 из 5 подов payment-api
14:35 UTC - Увеличены limits памяти, запущен rolling restart
14:38 UTC - Error rate снизился до нормы
14:40 UTC - Подтверждено восстановление, мониторинг 15 минут
14:55 UTC - Инцидент закрыт, постмортем запланирован на завтра
On-call
On-call - дежурство инженера, ответственного за реагирование на алерты и инциденты вне рабочих часов.
Ротация
Здоровая ротация on-call:
- Минимум 6-8 человек в ротации для избежания выгорания
- Смена длительностью 1-2 недели
- Primary и secondary on-call для эскалации
- Handoff-процедура при передаче дежурства с описанием текущих проблем и активных изменений
Escalation policies
# Пример политики эскалации (PagerDuty/OpsGenie формат)
escalation_policy:
name: payment-service
rules:
- level: 1
targets:
- type: on_call_schedule
id: payments-primary
escalation_timeout: 5m
- level: 2
targets:
- type: on_call_schedule
id: payments-secondary
escalation_timeout: 10m
- level: 3
targets:
- type: user
id: payments-team-lead
escalation_timeout: 15m
- level: 4
targets:
- type: user
id: engineering-director
escalation_timeout: 0 # финальная эскалацияRunbooks
Runbook - пошаговая инструкция для реагирования на конкретный алерт. Каждый алерт должен ссылаться на соответствующий runbook.
Структура runbook: алерт, приоритет, влияние, пошаговая диагностика, варианты решения по сценариям, условия эскалации, контакты. Каждый алерт должен ссылаться на соответствующий runbook. Полный пример runbook приведён в разделе “Практические примеры”.
Компенсация и well-being
On-call - это нагрузка на личную жизнь инженера. Здоровая on-call культура включает:
- Финансовую компенсацию за дежурства
- Отгул после ночного инцидента
- Ретроспективу on-call смены с анализом количества алертов
- Постоянное снижение количества ложных алертов
Blameless Postmortems
Постмортем - анализ инцидента после его разрешения с целью понять, что произошло, почему, и как предотвратить повторение. Blameless означает фокус на системных причинах, а не на поиске виноватых.
Культура blameless postmortems
Люди не являются корневой причиной. Если инженер внёс изменение, которое сломало продакшн, вопрос не “кто это сделал”, а “почему система позволила этому изменению попасть в продакшн без обнаружения проблемы”. Тесты, ревью, canary-деплой, мониторинг - все эти защитные барьеры должны были сработать.
Пример постмортема (сокращённый)
Инцидент: Payment API недоступен 32 минуты после деплоя v2.14.0 из-за memory leak в webhook handler. 12 400 пользователей не смогли совершить платежи, error budget израсходован на 40%.
Root Cause: при обработке batch webhook-ов объекты накапливались в массиве без очистки между итерациями, вызывая линейный рост потребления памяти до OOM-kill.
Contributing Factors: load testing не покрывал batch webhooks, canary window 2 минуты слишком короткий для memory leak, memory profiling отсутствовал в pipeline.
Action Items: добавить load test для batch webhooks (P1), включить memory profiling в CI (P1), увеличить canary window до 15 минут (P0), алерт на аномальный рост памяти (P1).
Lesson Learned: memory leaks проявляются только под нагрузкой и со временем - canary window должен быть достаточно длинным. Шаблон постмортема приведён в разделе “Практические примеры”.
Capacity Planning
Планирование ёмкости - процесс определения ресурсов, необходимых для обслуживания текущей и будущей нагрузки с заданным уровнем качества.
Forecasting
Прогнозирование нагрузки строится на исторических данных и понимании бизнес-динамики.
Органический рост - естественное увеличение числа пользователей. Анализируйте тренды за 6-12 месяцев, экстраполируйте с учётом сезонности.
Неорганический рост - маркетинговые кампании, запуск в новых регионах, вирусные эффекты. Требует взаимодействия с бизнес-командой для получения прогнозов.
# Пример: прогнозирование на основе линейного тренда (Prometheus)
predict_linear(
sum(rate(http_requests_total[1h]))[30d:1h],
86400 * 90 # прогноз на 90 дней
)
Load testing
Регулярное нагрузочное тестирование подтверждает, что система выдерживает ожидаемую нагрузку.
Типы нагрузочных тестов:
- Baseline test - текущая продакшн-нагрузка, подтверждает стабильность
- Stress test - постепенное увеличение нагрузки до обнаружения предела
- Spike test - резкий скачок нагрузки для проверки автоскейлинга
- Soak test - продолжительная нагрузка для обнаружения memory leaks и деградации
// k6 load test пример
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '5m', target: 100 }, // ramp up
{ duration: '10m', target: 100 }, // steady state
{ duration: '5m', target: 500 }, // stress
{ duration: '5m', target: 0 }, // ramp down
],
thresholds: {
http_req_duration: ['p(95)<300', 'p(99)<1000'],
http_req_failed: ['rate<0.001'],
},
};
export default function () {
const res = http.get('https://api.example.com/v1/products');
check(res, { 'status is 200': (r) => r.status === 200 });
sleep(1);
}Performance budgets и right-sizing
Установите лимиты потребления для каждого сервиса с запасом не менее 30% от пикового потребления. Регулярно анализируйте фактическое потребление vs выделенные лимиты:
# Prometheus: процент использования CPU относительно request
sum(rate(container_cpu_usage_seconds_total{namespace="production"}[5m])) by (pod)
/
sum(kube_pod_container_resource_requests{resource="cpu", namespace="production"}) by (pod)
Если потребление стабильно ниже 30% от request - ресурсы переалоцированы. Если регулярно приближается к 100% limit - необходимо увеличение.
Chaos Engineering
Хаос-инжиниринг - дисциплина экспериментирования на продакшн-системах для выявления слабых мест до того, как они станут причиной реальных инцидентов.
Принципы
- Определите steady state - нормальное, измеримое поведение системы
- Сформулируйте гипотезу - “система продолжит работать нормально при отказе компонента X”
- Спланируйте эксперимент - определите, какой сбой будете вносить, какие метрики наблюдать
- Минимизируйте blast radius - начинайте с малого, расширяйте постепенно
- Остановите эксперимент при первых признаках реального ущерба
Steady state hypothesis
Перед экспериментом зафиксируйте нормальные значения ключевых метрик:
experiment:
name: "Pod failure in payment-api"
steady_state:
error_rate: "< 0.1%"
p95_latency: "< 300ms"
throughput: "> 1000 rps"
hypothesis: "При убийстве 1 из 3 подов error rate < 0.5%, p95 latency < 500ms"
action: "kubectl delete pod payment-api-xyz -n production"
duration: 10m
abort_conditions: ["error_rate > 1%", "p95_latency > 2000ms"]Инструменты
Chaos Monkey (Netflix) - случайное завершение VM-инстансов в продакшне. Пионер хаос-инжиниринга.
Litmus Chaos - нативный для Kubernetes набор экспериментов. Поддерживает pod-kill, network-chaos, disk-fill, CPU-stress.
Gremlin - коммерческая платформа хаос-инжиниринга с UI и отчётами.
GameDays
GameDay - запланированное мероприятие, в ходе которого команда проводит хаос-эксперименты и практикует реагирование на инциденты.
Подготовка: определите сценарии, предупредите команды, подготовьте rollback-план, выберите время с минимальным трафиком. Проведение: эксперименты последовательно, метрики в реальном времени, остановка при превышении порогов. Результаты: список проблем, action items, обновление runbooks.
Blast radius
Всегда ограничивайте область воздействия эксперимента:
- Начинайте в staging-окружении
- В продакшне начинайте с одного пода, потом расширяйте
- Используйте feature flags для быстрого отключения эксперимента
- Никогда не проводите хаос-эксперименты на данных пользователей
Release Engineering
Инженерия релизов обеспечивает безопасную доставку изменений в продакшн с возможностью быстрого отката.
Canary releases
Canary-деплой направляет небольшой процент трафика на новую версию. Если метрики новой версии в норме, процент постепенно увеличивается.
# Argo Rollouts canary strategy
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: payment-api
spec:
replicas: 10
strategy:
canary:
steps:
- setWeight: 5
- pause: { duration: 5m }
- setWeight: 20
- pause: { duration: 10m }
- setWeight: 50
- pause: { duration: 10m }
- setWeight: 80
- pause: { duration: 5m }
analysis:
templates:
- templateName: success-rate
startingStep: 1Feature flags
Feature flags позволяют разделить деплой кода и выпуск функциональности. Код деплоится в продакшн, но новая функция включается через конфигурацию.
// Пример feature flags в Go
func (ff *FeatureFlags) IsEnabled(flag string, userID string) bool {
config := ff.store.Get(flag)
if config == nil {
return false
}
switch config.Strategy {
case "percentage":
return hash(userID) % 100 < config.Percentage
case "allowlist":
return contains(config.Users, userID)
default:
return false
}
}Traffic splitting
Распределение трафика между версиями на уровне инфраструктуры:
# Istio VirtualService для traffic splitting
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: payment-api
spec:
hosts:
- payment-api
http:
- route:
- destination:
host: payment-api
subset: stable
weight: 90
- destination:
host: payment-api
subset: canary
weight: 10Rollback стратегии
Автоматический rollback - система откатывается при нарушении SLO. Самый быстрый и надёжный способ.
# Argo Rollouts автоматический откат
strategy:
canary:
analysis:
templates:
- templateName: success-rate
# При неуспешном анализе - автоматический откат
abortScaleDownDelaySeconds: 30Ручной rollback - оператор принимает решение об откате. Используется, когда автоматика не может однозначно определить проблему.
# Kubernetes rollback
kubectl rollout undo deployment/payment-api -n production
# Argo Rollouts rollback
kubectl argo rollouts abort payment-api -n production
kubectl argo rollouts undo payment-api -n productionDatabase rollback - самый сложный тип отката. Миграции БД должны быть обратимо совместимыми. Expand-contract pattern: сначала добавляем новые столбцы/таблицы, потом мигрируем данные, потом удаляем старые.
Observability для SRE
Observability - способность понять внутреннее состояние системы по её внешним выходным данным. Три столпа: метрики, логи, трейсы.
Golden Signals
Google SRE выделяет четыре сигнала, которые необходимо мониторить для любого сервиса:
Latency - время обработки запроса. Разделяйте latency успешных и ошибочных запросов.
Traffic - объём нагрузки на систему. Для веб-сервиса - RPS, для стриминга - количество активных сессий, для хранилища - IOPS.
Errors - частота ошибок. Явные ошибки (HTTP 5xx) и неявные (успешный ответ с неправильным содержимым, ответ медленнее SLO).
Saturation - насколько “полна” система. Самый ограниченный ресурс - bottleneck. CPU, память, дисковый I/O, сетевая полоса, подключения к БД.
RED Method
Ориентирован на request-driven сервисы:
- Rate - количество запросов в секунду
- Errors - количество ошибочных запросов
- Duration - распределение latency запросов
# Grafana dashboard variables (Prometheus)
# Rate
sum(rate(http_requests_total{job="$service"}[5m]))
# Errors
sum(rate(http_requests_total{job="$service", status=~"5.."}[5m]))
/
sum(rate(http_requests_total{job="$service"}[5m]))
# Duration (p50, p95, p99)
histogram_quantile(0.95,
sum(rate(http_request_duration_seconds_bucket{job="$service"}[5m]))
by (le)
)
USE Method
Ориентирован на ресурсы инфраструктуры:
- Utilization - процент использования ресурса (CPU 75%)
- Saturation - очередь работы, которую ресурс не успевает обработать (runqueue length)
- Errors - количество ошибок ресурса (disk errors, network drops)
| Ресурс | Utilization | Saturation | Errors |
|---|---|---|---|
| CPU | node_cpu_seconds_total | node_load1 vs cores | dmesg machine check |
| Память | node_memory_MemAvailable | Swap usage, OOM kills | dmesg ECC errors |
| Диск | node_disk_io_time_seconds | node_disk_io_time_weighted | smartctl errors |
| Сеть | node_network_transmit_bytes | tc queue drops | node_network_receive_errs |
Когда какой метод применять
Golden Signals - универсальный подход для любого сервиса. RED - когда вы мониторите микросервисы и API. USE - когда вы мониторите инфраструктуру и ресурсы хоста.
Operational Overload
Операционная перегрузка возникает, когда команда SRE тратит слишком много времени на реактивную работу, и не остаётся времени на проактивное улучшение системы.
Managing interrupts
Разделите время команды на проектную работу и обработку прерываний:
- Выделите “дежурного по прерываниям” на каждый день
- Остальные члены команды работают над проектами без отвлечений
- Ротация дежурного ежедневно или еженедельно
- Если дежурный перегружен, это сигнал о системной проблеме
Automation ROI calculation
Перед автоматизацией оцените окупаемость:
Время на ручное выполнение: T_manual
Частота выполнения в год: F
Стоимость часа инженера: C_hour
Время на автоматизацию: T_auto
ROI = (T_manual × F × C_hour × Years) / (T_auto × C_hour)
Пример:
Ручной деплой: 30 минут
Частота: 200 раз/год
Стоимость часа: $80
Время на автоматизацию CI/CD: 40 часов
Ежегодная экономия: 0.5ч × 200 × $80 = $8 000
Стоимость автоматизации: 40ч × $80 = $3 200
Окупаемость: 5 месяцев
Правило xkcd
Если задача занимает 5 минут и выполняется 5 раз в день, за 5 лет вы потратите на неё 5 недель. Если автоматизация занимает 1 неделю, она окупится за год.
Помимо прямой экономии времени, автоматизация даёт:
- Консистентность выполнения
- Снижение человеческих ошибок
- Документирование процесса в виде кода
- Возможность масштабирования
Практические примеры
Шаблон postmortem
# Постмортем: [Краткое описание инцидента]
## Метаданные
| Поле | Значение |
|------|----------|
| Дата | YYYY-MM-DD |
| Длительность | X минут |
| Severity | SEVN |
| Incident Commander | Имя |
| Статус | Draft / Reviewed / Complete |
## Краткое описание
Одно-два предложения о том, что произошло и каково влияние.
## Влияние
- Количество затронутых пользователей
- Потерянная выручка
- Влияние на SLO / error budget
## Timeline (UTC)
| Время | Событие |
|-------|---------|
| HH:MM | Событие 1 |
## Root Cause
Техническое описание корневой причины. Не "кто", а "что" и "почему".
## Contributing Factors
Факторы, усилившие проблему или замедлившие восстановление.
## Что сработало хорошо / Что можно улучшить
## Action Items
| ID | Действие | Ответственный | Срок | Приоритет | Статус |
|----|----------|---------------|------|-----------|--------|
| AI-1 | Действие | Имя | Дата | P0/P1/P2 | TODO |
## Lessons LearnedПример runbook
# Runbook: Высокая утилизация CPU на PostgreSQL
## Алерт
PostgreSQL_HighCPU - CPU usage > 80% в течение 10 минут
## Приоритет
SEV3 (при > 95% - SEV2)
## Влияние
Замедление запросов к БД, потенциальная недоступность сервисов
## Диагностика
1. Dashboard: https://grafana.internal/d/postgresql-overview
2. Количество активных соединений:
SELECT count(*) FROM pg_stat_activity WHERE state = 'active';
3. Тяжёлые запросы:
SELECT pid, now() - query_start AS duration, query
FROM pg_stat_activity
WHERE (now() - query_start) > interval '30 seconds'
AND state != 'idle'
ORDER BY duration DESC;
4. Проверить блокировки:
SELECT blocked_locks.pid, blocking_locks.pid, blocked_activity.query
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_locks blocking_locks
ON blocking_locks.locktype = blocked_locks.locktype
WHERE NOT blocked_locks.granted;
## Решение
### Долгий запрос блокирует ресурсы
SELECT pg_cancel_backend(<pid>);
-- Если не помогло через 30 секунд:
SELECT pg_terminate_backend(<pid>);
### Отсутствующий индекс
SELECT relname, seq_scan, seq_tup_read, idx_scan
FROM pg_stat_user_tables WHERE seq_scan > 1000
ORDER BY seq_tup_read DESC;
CREATE INDEX CONCURRENTLY idx_name ON table_name(column);
### Bloat таблиц
VACUUM (VERBOSE, ANALYZE) table_name;
## Эскалация
- CPU > 95% более 5 минут и причина не найдена
- Проблема связана с репликацией
- Контакт: #dba-oncall в SlackРекомендуемые ресурсы
- “Site Reliability Engineering” (Google) - фундаментальная книга, доступна бесплатно на sre.google/sre-book
- “The Site Reliability Workbook” (Google) - практическое продолжение с примерами
- “Implementing Service Level Objectives” (Alex Hidalgo) - глубокое погружение в SLI/SLO
- “Chaos Engineering” (Casey Rosenthal, Nora Jones) - принципы хаос-инжиниринга от инженеров Netflix