awesome-everything EN
↑ Обратно к восхождению

Наблюдаемость

Iceberg SLI, математика составного SLO и SLA vs SLO

Суть SLI только на 2xx пропускает ошибки корректности, 4xx-баги и высоколатентные успехи — айсберг. Математика составного SLO для N сервисов последовательно — произведение; параллельный hedging и идемпотентные retry — архитектурные рычаги. SLA — контракт и жёстче SLO по определению.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 16 min

Checkout-сервис имеет 99.9% availability SLO и он зелёный. Клиенты сообщают о дублированных списаниях. SLO не ошибочен — он измеряет не то.

Выбор SLI: failures-айсберг

SLI, ломающий команды, — тот, что не коррелирует с болью пользователя. Классическая ошибка: определить availability SLI только на 5xx-ответах. Что это пропускает:

4xx из-за внутреннего бага: 422, выброшенный из-за ошибки сериализации в сервисе, возвращает код ошибки клиента — не считается как серверный отказ, не считается как нарушение SLO. Запрос пользователя упал. SLO зелёный.

Высоколатентный успех: Запрос, занявший 30 секунд, но вернувший 200 OK, проходит availability SLI. Пользователь испытал отказ (30 с выше любого разумного порога latency). Если нет latency SLO, SLO-система пропускает это полностью.

Ошибки корректности: Списание подтверждено пользователю, но отсутствует в бэкенде. Результат поиска вернул 200 с устаревшими данными трёхчасовой давности. HTTP-статус был нормальным; данные были неверными. SLI это не измерил.

Потерянные события: Сервис сообщений, тихо теряющий 0.1% уведомлений — нет ошибки, нет таймаута, просто нет доставки. SLI на эндпойнт отправки показывает 100% успех. Сообщение пользователя никогда не пришло.

Сениорный паттерн: выбор SLI начинается с «какой плохой исход для пользователя?» и затем выводит измерение.

Для checkout-сервиса плохие исходы:

  • Отказ списания: → availability SLI на payment эндпойнт
  • Слишком медленное списание: → latency SLI (99-й перцентиль под 3с)
  • Списание подтверждено, но отсутствует в бэкенде: → correctness SLI (confirmed_charges_matched / confirmed_charges_total, из фонового reconciliation)
  • Дублированное списание: → uniqueness SLI (distinct charge IDs / total charges attempted)

Несколько SLI на journey — норма. SLO-платформа агрегирует их worst-of соединением: journey SLO нарушается если любой из SLI нарушает свою цель.

Почему это работает

Дублированное списание, вернувшее 2xx, проходит availability SLI — сервис был «доступен». Ошибка корректности невидима для мониторинга только на доступность. Это айсберг: доступность — видимые 10%, корректность и свежесть — 90% под ватерлинией. Команды, выпустившие 99.9% availability SLO и всё равно имеющие P0-инцидент корректности каждый квартал, обычно запускают iceberg SLI.

Математика составного SLO

User journey через N независимых сервисов имеет потолок:

journey_slo = ∏(S₁, S₂, ..., Sₙ)

При независимых отказах каждый сервис должен успешно завершиться для успеха journey. Пять сервисов по 99.9% каждый: 0.999⁵ ≈ 0.995 — потолок journey 99.5%, не 99.9%.

При зависимых отказах потолок ниже. Разделяемая БД, шумный сосед, региональный сетевой инцидент: когда региональная зависимость деградирует, все пять сервисов могут отказывать одновременно. Предположение о независимости нарушается, и ∏Sᵢ — оптимистичная верхняя граница. Реальная доступность journey в событии коррелированного отказа хуже, чем предсказывает математика.

Два архитектурных рычага для поднятия потолка:

Параллельный hedging: Отправить два запроса двум репликам, взять первый успешный. Вероятность что оба упадут: (1 - S)². При 99.9% на реплику: 0.001² = 0.000001 — доступность journey вырастает до 99.9999%. Цена: двойной трафик, двойная нагрузка на бэкенд, нужно обработать «лишний» ответ (отменить или дедуплицировать). Подходит для read-heavy путей где удвоение трафика приемлемо.

Идемпотентные retry с backoff: При транзиентном отказе, retry с экспоненциальным backoff. Один retry превращает большинство транзиентных отказов в успехи. При 99.9% на попытку, один retry даёт: 1 - (0.001)² ≈ 99.9999%. Цена: latency (retry добавляет минимум один round-trip). Эндпойнт должен быть идемпотентным — retry списания не может создать дублированное списание. Idempotency keys (уникальный ID попытки, генерируемый клиентом) это обеспечивают.

Превращение архитектуры в SLO-арифметику: «Добавить retry?» становится измеримым. Если текущий failure rate на payment-вызов — 0.05%, один retry снижает его до (0.0005)² ≈ 0.000025% — ниже любого порога. Выигрыш бюджета в сокращении отказов в месяц поддаётся расчёту и сравнению с ценой latency в P99-терминах.

ПодходPer-service SLOПотолок journeyЦена
5 сервисов последовательно, без митигации99.9% каждый~99.5%Нет
Идемпотентные retry на критическом пути99.9% на попытку>99.99%Добавленная latency на retry-путях
Параллельный hedging на одном сервисе99.9% на реплику>99.99%2× трафик на этот сервис
Сокращение journey до 3 сервисов99.9% каждый~99.7%Архитектурный рефакторинг

Latency SLO и порог счастья

Latency SLO требует порога — насколько медленно — «достаточно медленно, чтобы считать отказом»?

Перцептивные границы из UX-исследований:

  • 100мс: перцептивный предел «мгновенного» — ниже этого UI воспринимается как отзывчивый
  • 200мс: верхняя граница воспринимаемой немедленности для интерактивных элементов
  • 1с: порог выше которого пользователи замечают задержку
  • 3с: порог выше которого значимая доля пользователей бросает веб-запрос
  • 10с+: фактически таймаут для интерактивных use cases

Для request-driven API обслуживающего UI: 200мс — стандартный порог latency SLO. Для backend API-вызовов между сервисами: 1с — распространено. Для batch jobs: минуты-часы в зависимости от бизнес-контекста.

Мультипороговые SLO ловят tail-latency, прячущийся за одним перцентилем. «99% под 500мс» может проходить, пока деградированный хвост проваливает «90% под 100мс». Production-grade паттерн: определить оба порога, AND-ить с worst-of логикой. Сервис проходит latency SLO только если оба порога выполнены.

SLA vs SLO: не путать

Правильное соотношение: SLO_внутренний > SLA_внешний (жёстче внутренняя цель).

Типичный паттерн:

  • Customer SLA: 99.9% доступности
  • Внутренний SLO: 99.95% доступности
  • Буфер: 0.05 процентных пункта

Буфер поглощает инциденты: когда внутренний SLO горит, команда расследует и фиксит до порога нарушения SLA. Error budget policy срабатывает на SLO, не на SLA. Клиенты не видят внутренний SLO — они видят выполнено ли SLA, что почти всегда так, потому что команда реагировала на более жёсткую внутреннюю цель.

Ставить SLO == SLA — ловушка новичка. Каждый внутренний инцидент становится риском нарушения контракта. Error budget для SLO-enforcement точно совпадает с error budget для правовой ответственности. Нет буфера для поглощения нормального операционного шума (деплои, деградации зависимостей, maintenance).

Размер буфера зависит от типичного времени реагирования сервиса и структуры поддержки. 0.05–0.5 процентных пункта — распространённый диапазон. Для сервиса со средним временем детекции + реагирования 4 часа, буфер 0.5pp даёт команде пространство для нахождения и фикса до нарушения SLA. Для сервиса с 2-минутным автоматическим rollback, буфер 0.05pp может быть достаточным.

Викторина

SLI checkout-journey команды считает запрос 'хорошим' если возвращается 2xx. После релиза клиенты сообщают о дублированных списаниях — но никакого SLO-горения нет. Что не так с SLI?

Викторина

Внутренний SLO установлен на 99.9%, равный customer SLA. Почему это проблема?

Вспомните перед уходом
  1. 01
    Назови три failure mode'а которые пропускает 2xx-only availability SLI для checkout-сервиса.
  2. 02
    Объясни как идемпотентные retry улучшают математику составного SLO и какое архитектурное условие они требуют.
  3. 03
    Каково правильное соотношение между SLA и SLO, и почему SLO должен быть жёстче?
Итог

Дизайн SLI должен начинаться с user-facing плохих исходов, а не с HTTP-статусов. 2xx-only availability SLI пропускает ошибки корректности, 4xx из-за внутренних багов, высоколатентные успехи и тихие потери — айсберг под ватерлинией. Несколько SLI на journey (доступность + latency + корректность), агрегированных с worst-of логикой — production-паттерн. Математика составного SLO перемножается: N сервисов последовательно по 99.9% даёт потолок 0.999^N. Идемпотентные retry и параллельный hedging — основные архитектурные рычаги для поднятия потолка, каждый с определённой ценой. SLA — контракт с клиентами с финансовыми штрафами; SLO — внутренняя цель. Установка SLO жёстче SLA на 0.05–0.5pp создаёт буфер позволяющий команде реагировать до начала юридической ответственности. SLO == SLA — ловушка новичка.

Связанные уроки
встречается в167
Продолжить восхождение ↑Продакшн-отказы SLO, самонаблюдаемость, безопасность и общая картина
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.