Опирается на правила:
R-OBS-SLO-1…R-OBS-SLO-4иR-OBS-SLO-X1…R-OBS-SLO-X3из Observability Style Guide → раздел 7. SLO и алерты.
Важно знать
- Каждый critical-endpoint имеет SLO (например, 99.9% successful + p95 < 500ms на rolling 30-day window).
- Multi-window multi-burn-rate alerts по Google SRE Workbook: fast burn (1h, rate > 14.4) и slow burn (6h, rate > 6).
- Error budget: 99.9% target = 43 минуты downtime/month как бюджет. 100% — нечем оперировать.
- Алерт на исчерпание бюджета (< 10%) → команда переключается с features на reliability.
- Алерты отдельные от SLO: infra (JVM heap, HikariCP saturation), domain (бизнес-фейлы), Resilience (CB open), Kafka lag, cache hit rate.
- Alert на каждый ERROR → fatigue → команда игнорирует. Фильтр: повторяющиеся группируются, единичные не алертят.
- Каждый alert имеет runbook. PagerDuty в 3 ночи без инструкции — эскалация без действия.
SLO (Service Level Objective) — это обещание уровню обслуживания, который сервис даёт пользователям. Не «всё всегда работает», а «99.9% запросов успешны в течение 30-day window». Разница принципиальная: появляется error budget, появляется возможность приоритизации reliability vs features.
SLO для critical endpoints
R-OBS-SLO-1: для каждого critical-endpoint — две метрики.
| Endpoint | Availability SLO | Latency SLO |
|---|---|---|
POST /orders | 99.9% non-5xx | p95 < 500ms |
POST /payments | 99.95% non-5xx | p95 < 1s |
GET /orders/{id} | 99.95% non-5xx | p95 < 200ms |
GET /search?q= | 99.5% non-5xx | p95 < 800ms |
Бизнес выбирает target вместе с product owner: «сколько вы готовы платить за дополнительную девятку?». 99.99% (52 мин/год) на порядок дороже 99.9% (8.7 ч/год) — другая архитектура, другая инфра.
Расчёт SLI (Service Level Indicator) в Prometheus:
# Availability SLI
sum(rate(http_server_requests_seconds_count{uri="/orders",method="POST",status!~"5.."}[30d]))
/
sum(rate(http_server_requests_seconds_count{uri="/orders",method="POST"}[30d]))
# Latency SLI
histogram_quantile(0.95,
sum by (le) (rate(http_server_requests_seconds_bucket{uri="/orders",method="POST"}[30d]))
)
Multi-window multi-burn-rate
R-OBS-SLO-2: классический подход SRE Workbook chapter 5.
Идея: SLO 99.9% даёт error budget 0.1% за 30 дней. Если за 1 час расходуется 5% бюджета — это быстрое сжигание, при таком темпе бюджет кончится за 20 часов. Это алерт.
Формула burn rate:
burn_rate = (error_rate_in_window) / (1 - SLO_target)
Для SLO 99.9% и window 1h:
- burn rate > 14.4 → 5% бюджета сгорает за 1 час
- burn rate > 6 (window 6h) → 5% бюджета сгорает за 6 часов
- burn rate > 1 (window 24h) → нормальная скорость
- alert: OrdersSloFastBurn
expr: |
(
sum(rate(http_server_requests_seconds_count{uri="/orders",method="POST",status=~"5.."}[1h]))
/
sum(rate(http_server_requests_seconds_count{uri="/orders",method="POST"}[1h]))
) > (14.4 * (1 - 0.999))
for: 2m
annotations:
runbook: https://runbooks.internal/orders-slo-fast-burn
- alert: OrdersSloSlowBurn
expr: |
(
sum(rate(http_server_requests_seconds_count{uri="/orders",method="POST",status=~"5.."}[6h]))
/
sum(rate(http_server_requests_seconds_count{uri="/orders",method="POST"}[6h]))
) > (6 * (1 - 0.999))
for: 15m
annotations:
runbook: https://runbooks.internal/orders-slo-slow-burn
Fast burn будит ops немедленно — потенциальный outage. Slow burn создаёт ticket — деградация, не критичная, но требует разбора.
Error budget exhaustion
R-OBS-SLO-3: отдельный алерт на остаток бюджета.
# Сколько бюджета осталось (0 = весь израсходован, 1 = весь свободен)
1 - (
(1 - <availability_sli_30d>) / (1 - <slo_target>)
)
Алерт если < 10%:
- alert: OrdersErrorBudgetExhausted
expr: <budget_remaining_expression> < 0.1
for: 1h
annotations:
summary: "Только 10% error budget осталось"
description: |
Команда переключается с features на reliability.
Релизы рискованных изменений приостановлены до восстановления бюджета.
Это не «срочно чинить ночью», а сигнал бизнесу: следующий месяц команда фокусируется на устойчивости.
Алерты отдельные от SLO
R-OBS-SLO-4: SLO — про user-facing успешность. Есть отдельные категории алертов.
| Категория | Метрика | Действие |
|---|---|---|
| Infrastructure | jvm_memory_used / max > 0.85, hikaricp_connections_pending > 0 | SRE: scale, tune |
| Domain | order_failed_total rate > 100/min | Product: что-то изменилось в данных |
| Resilience | resilience4j_circuitbreaker_state{state="open"} | внешний сервис недоступен |
| Cache | cache_hits / (hits+misses) < 0.7 | tune TTL / size |
| Kafka consumer lag | kafka_consumer_lag_max > 10000 | scale consumers |
Эти алерты не обязательно нарушают SLO — но дают раннее предупреждение. Resilience CB open → запросы уходят на fallback → SLO ещё в норме, но проблема назревает.
Что запрещено
Alert на каждый ERROR
R-OBS-SLO-X1: главная причина alert fatigue.
Сценарий: каждый log.error(...) → алерт. Один client пытается за минуту 1000 раз с невалидным payload → 1000 ERROR → 1000 алертов → команда мьютит канал → пропускает реальный инцидент.
Группировка / фильтрация на уровне alerting:
- ERROR одного класса (
ValidationException) повторяющийся 100 раз/мин → один алерт с count. - Единичные
ValidationException— не алерт (это нормальный flow для bad input). ServiceUnavailableExceptionповторяющийся → один алерт с указанием external system.
- alert: HighErrorRate
expr: sum by (exception) (rate(app_errors_total[5m])) > 1
for: 5m
annotations:
runbook: https://runbooks.internal/high-error-rate
SLO без error budget
R-OBS-SLO-X2: 100% target — это обещание не ошибаться никогда, что невозможно.
- Каждая ошибка → нарушение → срочно чинить.
- Команда боится релизов («любая регрессия = инцидент»).
- Не остаётся ресурса на reliability-work.
99.9% даёт 43 минуты downtime/month как «легально потраченный» бюджет — раз в неделю можно потерпеть короткую деградацию ради рискованного релиза.
99.99% (52 мин/год) — намного дороже: multi-region active-active, immediate failover, отдельная инфра. Бизнес выбирает осознанно.
Алерты без runbook'ов
R-OBS-SLO-X3: PagerDuty в 3 ночи будит дежурного. Алерт: «p95 latency на /orders > 1s».
Без runbook:
- Дежурный открывает Grafana.
- Не знает, кому звонить.
- Не знает, что трогать.
- Эскалирует тимлиду → тимлиду эскалация в 3 ночи без контекста.
С runbook (https://runbooks.internal/orders-latency-high):
- Проверить
hikaricp_connections_pending— если > 0, scale up DB или приложение. - Проверить
external_calls_duration_seconds{system="payment-provider"}— если > 2s, есть инцидент у payment, ack and wait. - Если ни 1 ни 2 — escalate to
#order-service-oncall.
Runbook — обязательная часть каждого алерта.
Что запрещено — таблица
| Антипаттерн | Правило | Что взамен |
|---|---|---|
| Alert на каждый ERROR в логах | R-OBS-SLO-X1 | group by exception, rate threshold |
| SLO 100% target | R-OBS-SLO-X2 | 99.9% (43m/mo) или 99.95% / 99.99% |
| Алерт без runbook URL | R-OBS-SLO-X3 | annotations.runbook ссылка обязательна |
| Один универсальный алерт «что-то сломалось» | R-OBS-SLO-4 | категории: infra / domain / resilience / SLO burn |
| Burn rate window 30d без short window | R-OBS-SLO-2 | multi-window: 1h fast + 6h slow |
| Латентность SLO без percentile | R-OBS-SLO-1 | p95 или p99, не avg |
Alert на metric «когда-то превысила» (без for:) | R-OBS-SLO-2 | for: 2m (fast) / for: 15m (slow) |
Куда дальше
- Observability → раздел 7. SLO и алерты — нормативные формулировки.
- Metrics —
http_server_requests_secondsдля расчёта SLI. - Tracing — детальный разбор burn'а через traces с ошибками.
- Health checks — почему probe не для бизнес-SLO.
- Resilience → observability — Circuit Breaker state metrics для алертов.
- Caching → observability — cache hit rate threshold.
- Kafka → observability — consumer lag alerts.
- Google SRE Workbook ch.5 — Alerting on SLOs — первоисточник multi-window burn rate.