{ "index": 151, "slug": "editorial-2023-10-field-sli-slo", "title": "SLI/SLO в релизном разговоре: от красного графика к проверяемому решению", "excerpt": "Как связать SLI, SLO и error budget с пользовательским путём, окном измерения и обратимым действием — и не выдать один график за доказательство инцидента или автоматический запрет релиза.", "contentHtml": "

В день релиза на панели краснеет error budget. Один инженер говорит: «бюджет почти закончился». Другой просит не задерживать исправление. On-call не может показать, какой пользовательский путь пострадал, за какой период считался показатель и какие события попали в знаменатель. Команда спорит о цвете, а не о данных.

\n

Цена ошибки двойная. Шумный сигнал может остановить безопасное изменение. Слишком узкий SLI может пропустить отказ после точки измерения, и команда выпустит рискованный релиз. В обоих случаях SLO превращается в отчётность: число есть, но оно не подсказывает следующий безопасный шаг.

\n

Тезис статьи простой: error budget не принимает решение вместо команды. Он запускает проверяемую петлю. Сначала нужно подтвердить договор SLI: что измеряем, для кого, в каком окне и по какой формуле. Затем нужно проверить контекст и выбрать действие по policy. Только после этого можно обсуждать rollout, паузу или исправление.

\n

Механизм: сигнал, цель, бюджет и policy

\n

SLI — количественная мера свойства сервиса. Например, доля запросов, которые завершились полезным результатом, или доля операций с задержкой ниже порога. SLO — целевое значение этой меры в заданных условиях. Error budget — допустимая часть неуспеха в том же договоре. Если target равен 99%, бюджет равен 1% eligible-событий за указанное окно.

\n

Формула сама по себе ничего не решает. Для success ratio нужны как минимум scope, eligible count, good count, target и window. Scope задаёт путь пользователя и границу ответственности. Eligible определяет знаменатель. Good определяет успешный исход. Window задаёт период сравнения. Policy связывает состояние бюджета с действием и владельцем.

\n
eligible = 1000\ngood = 994\ntarget = 0.99\nactual = good / eligible       // 0.994\nallowed_bad = eligible * (1 - target) // 10\nactual_bad = eligible - good          // 6\nremaining = allowed_bad - actual_bad  // 4\n\n// Все числа учебные. Источник событий отсутствует.\n// Результат не описывает production-доступность.
\n

В этом примере остаются четыре условные единицы бюджета. Это арифметика модели, а не факт о сервисе. Если исключить отменённые операции, изменить окно или считать только ответы одного backend, результат станет другим. Поэтому процент без версии договора нельзя сравнивать с прошлым процентом и нельзя использовать как самостоятельную причину для блокировки.

\n

Почему scope важнее красивого процента

\n

Пользователь оценивает путь, а не внутренний HTTP-ответ. Запрос может получить код 202, но очередь позже отклонит операцию. Backend может ответить быстро, пока клиент ждёт подтверждение в другом компоненте. Если SLI измеряет только первый ответ, он может быть технически точным и продуктово бесполезным.

\n

Сначала назовите действие пользователя: например, «отправить заказ и получить подтверждение». Затем определите границу: где путь считается завершённым, какие отказы входят в оценку, кто владеет источником событий. Если путь нельзя связать с наблюдаемым результатом, не объявляйте готовый SLO. Сначала сократите вопрос или добавьте нужный сигнал.

\n

Знаменатель также требует явного правила. Eligible-события нельзя выбирать по удобству. Если фильтр исключает таймауты, повторные попытки или отмены, запишите причину и отрицательный пример. Иначе команда улучшит процент удалением сложных случаев. Это не повышение надёжности, а изменение измеряемой популяции.

\n

Окно определяет, чему доверять

\n

Фиксированное окно проще объяснить: события с 1 по 28 число сравниваются с предыдущим таким же периодом. Скользящее окно быстрее показывает недавнее ухудшение, но каждый момент измерения содержит немного иной набор событий. В обоих вариантах нужно назвать часовой пояс, границы, задержку поступления событий и правило пересчёта.

\n

Низкий трафик усиливает цену одного отказа. При десяти eligible-событиях один failure меняет ratio сильнее, чем при миллионе. Это не означает, что малотрафиковый путь нельзя измерять. Это означает, что порог, окно и способ реакции надо выбирать вместе. Иногда полезнее ticket и ручной разбор, чем срочное оповещение на каждое колебание.

\n
Симптом → причина → проверка → действие
СимптомПричинаПроверкаДействие
Процент стал краснымНеизвестны окно и версия формулыСверить SLI-contract, границы и периодПриостановить интерпретацию, запросить источник
Команды считают доступность по-разномуРазные eligible и goodСравнить запросы, исключения и отрицательные случаиЗафиксировать одну формулу и владельца
Процент хороший, путь сломанSLI измеряет ранний backend-ответПройти пользовательский сценарий до результатаРасширить scope или добавить отдельный SLI
Один отказ резко изменил ratioМалое окно или низкий трафикПосчитать eligible и проверить распределение событийВыбрать устойчивое окно и ручной response
Красный график блокирует любой релизУ policy нет исключений и владельцаПроверить обратимость, срочность и evidenceСузить rollout, исправить, отложить или продолжить по policy
\n
\"Петля
Петля решения отделяет измерение от причины и ручного решения. Иллюстрация показывает учебную схему, а не мониторинг, CI-gate или журнал инцидента.
\n

Пример policy для релизного разговора

\n

Policy должна отвечать на пять вопросов. Какое состояние бюджета запускает разбор? Какие данные обязан принести владелец? Какое действие обратимо? Кто принимает решение? Когда команда пересматривает договор? Запись «при красном графике остановить всё» не отвечает ни на один вопрос до конца.

\n

Практичная ветка может выглядеть так: если формула или scope неизвестны, решение откладывают до проверки данных. Если договор подтверждён, но причина неясна, открывают разбор и уменьшают exposure рискованного изменения. Если budget exhausted, non-urgent rollout приостанавливают, а обязательное исправление оценивают отдельно с владельцем и планом отката. Если сигнал восстановился, повторяют ту же проверку; новый процент не должен появиться из другой формулы.

\n

Такая policy не запрещает каждый релиз. Она не разрешает и каждый релиз. Она задаёт минимальное evidence и оставляет полномочие у владельца. Security fix, изменение инфраструктуры и продуктовый rollout могут иметь разные уровни срочности, поэтому один универсальный gate создаёт ложную уверенность.

\n

Порядок действий

\n
  1. Сформулируйте наблюдаемую проблему: какой пользовательский путь, симптом и цена ошибки обсуждаются.
  2. Зафиксируйте версию SLI-contract: scope, eligible, good, exclusions, target, window и источник событий.
  3. Пересчитайте показатель на небольшом проверяемом наборе и добавьте отрицательный пример. Если две команды получают разные значения, сначала устраните расхождение.
  4. Отделите сигнал от причины. В разрешённой среде проверьте версию, зависимость, класс ответов, задержку, очередь или данные, которые связаны с тем же периодом.
  5. Выберите действие по policy: исправить причину, сузить rollout, отложить несрочное изменение или продолжить с явным контролем.
  6. Назначьте владельца и план обратного действия. Укажите, что вернуть, кто это сделает и каким наблюдением подтвердить результат.
  7. После действия примените ту же формулу и критерий. Если результат не изменился, пересмотрите гипотезу, а не denominator.
\n

Ограничения отрицательного пути

\n

Один SLI не объясняет корневую причину. Trace, log и dashboard помогают только тогда, когда они относятся к той же операции, версии и периоду. Корреляция не доказывает причинность. Красный budget не доказывает инцидент. Зелёный budget не доказывает, что весь пользовательский путь работает.

\n

Учебная арифметика выше не читает файлы, часы, monitoring, CI, сеть, HTTP или production-конфигурацию. Она не создаёт alert, не меняет rollout и не выдаёт разрешение на выпуск. В реальной системе эти полномочия должны находиться в явно назначенных инструментах и runbook. Если команда не может проверить источник или обратить действие, это ограничение нужно записать до решения.

\n

Проверяемый критерий готовности

\n

Разбор готов, когда другой инженер без устного контекста может воспроизвести число и понять решение. В записи есть пользовательский путь, версия формулы, eligible и good, target, окно, источник, владелец, выбранное действие, план отката и повторная проверка. Есть хотя бы один отрицательный пример: событие, которое нельзя молча исключить, или путь, который текущий SLI не покрывает.

\n

Релизный разговор также готов, если команда может ответить на три вопроса: что измеряем, почему этому сигналу можно доверять в данном решении и что произойдёт при ухудшении. Если на любой вопрос отвечает только цвет графика, договор ещё не готов.

\n

Проверяемые источники

" }