{ "index": 151, "slug": "editorial-2023-10-field-sli-slo", "title": "SLI/SLO в релизном разговоре: от красного графика к проверяемому решению", "excerpt": "Как связать SLI, SLO и error budget с пользовательским путём, окном измерения и обратимым действием — и не выдать один график за доказательство инцидента или автоматический запрет релиза.", "contentHtml": "
На релизе график error budget становится красным. Один инженер предлагает остановить выкладку, другой просит не задерживать исправление. Но никто не может сразу ответить, какой пользовательский путь измеряет график, какие события входят в знаменатель и за какое окно посчитан расход. В итоге команда обсуждает цвет панели вместо проверяемого факта.
\nОшибка в такой ситуации стоит дорого в обе стороны. Слабый SLI может оставить сломанным путь, который сервер формально считает успешным. Нечёткая policy может остановить безопасное изменение из-за одного нерепрезентативного всплеска. Поэтому SLO полезен не как печать «можно» или «нельзя», а как часть петли: измерили, сравнили с целью, проверили контекст, выбрали действие, повторили измерение.
\nНиже — практический способ провести этот разговор. Сначала зафиксируем контракт показателя, затем разберём знаменатель и окно, после чего превратим расход бюджета в ограниченное и обратимое решение. Все числа в примерах учебные: они показывают арифметику и порядок проверки, но не описывают конкретную production-систему.
\nSLI (service level indicator) — количественная мера свойства сервиса: например, доля успешных запросов или доля запросов, завершившихся быстрее порога. SLO (service level objective) — целевое значение SLI при явно названных условиях. Error budget — допустимая часть неуспеха за то же окно. Для цели 99% это 1% событий, которые могут не соответствовать критерию, если договор считает их одинаково.
\nМинимальный контракт должен назвать пользовательский scope, способ измерения, eligible-события, good-события, target и window. Scope говорит, какой результат защищаем. Eligible задаёт знаменатель. Good задаёт числитель. Window задаёт период, в котором результат сравнивают с целью. Policy добавляет владельца и действие, но не меняет саму формулу.
\neligible = 1000\ngood = 994\ntarget = 0.99\nactual = good / eligible // 0.994 = 99.4%\nallowed_bad = eligible * (1 - target) // 10\nactual_bad = eligible - good // 6\nremaining_bad_capacity = allowed_bad - actual_bad // 4\n\n# Учебные числа: здесь нет источника событий и реального окна.\nВ учебной модели осталось место ещё для четырёх неуспешных событий до цели 99%. Это не означает, что сервис «на 99,4% надёжен» во всех смыслах: код 202 может лишь поставить операцию в очередь, а клиентский JavaScript может сломаться после ответа API. Если изменить exclusions, источник или границу завершения, изменятся eligible и good, а вместе с ними — весь вывод.
\nСерверная метрика удобна, но удобство не делает её пользовательским SLI. Запрос «создать заказ» может получить 202, а очередь позднее отклонит заказ. Или backend ответит за 80 мс, пока браузер ждёт загрузки скрипта и не показывает подтверждение. Такой backend-SLI честно описывает свою точку измерения, но не весь путь.
\nФормулировка должна начинаться с действия: «пользователь отправляет заказ и видит подтверждение». Затем задайте границу завершения: получение 202, появление записи в заказах или видимый экран подтверждения. Выберите источник, который действительно видит эту границу: серверный лог, black-box проверка или клиентская телеметрия. У каждого способа своя цена покрытия и сопровождения.
\nНе смешивайте спецификацию и реализацию. Спецификация может звучать как «доля заказов, подтверждённых не позднее пяти минут». Реализация через лог API не увидит отказы до backend; реализация через браузерный synthetic-проверяющий охватит доступность пути, но может не отражать всех клиентов. В договоре нужно записать, какой пробел принят и зачем.
\nEligible — не «все записи, которые удобно посчитать», а заранее определённая популяция. Таймауты, повторные попытки, отмены и некорректные входы нельзя молча выкинуть только потому, что они ухудшают процент. Если событие исключается, запишите техническую причину, владельца правила и отрицательный пример. Иначе команда улучшает отчёт, меняя объект измерения.
\nОкно тоже часть контракта. Скользящее окно сохраняет недавний сбой в расчёте и не обнуляет его в начале календарного месяца. Календарное окно удобнее для отчётности и планирования, но посреди периода сложнее оценить, сколько трафика ещё поступит. Для обоих вариантов укажите часовой пояс, границы, задержку событий и правило пересчёта.
\nНа малом трафике один отказ заметно меняет ratio. Это не запрет на SLO, а причина не строить срочный автоматический вывод на малой выборке. Можно увеличить окно, поднять минимальное число eligible-событий для page или отправлять такой сигнал в ticket на ручной разбор. Порог реакции выбирается вместе с формулой, а не после неё.
\n| Наблюдение | Возможная причина | Проверяем | Следующее действие |
|---|---|---|---|
| Красный budget, но неизвестна формула | Смешаны окно, exclusions или версия запроса | Сверяем SLI-контракт и исходные выборки | Не принимать релизное решение до восстановления evidence |
| Команды получили разные проценты | Разные eligible, good или часовой пояс | Сравниваем запрос, период, фильтры и повторные попытки | Назначаем владельца одной версии расчёта |
| Зелёный SLI, но путь не работает | Точка измерения раньше пользовательского результата | Проходим сценарий до подтверждения | Расширяем scope или добавляем отдельный клиентский SLI |
| Один отказ сильно изменил процент | Малое окно или низкий трафик | Считаем объём и распределение событий | Меняем окно или переводим сигнал в ручной разбор |
| Красный график блокирует любой релиз | Policy не различает срочность и обратимость | Проверяем blast radius, rollback и тип изменения | Сужаем rollout, откатываемся или продолжаем с контролем |
Policy — это не фраза «при красном остановить всё». В ней должны быть условие, evidence, владелец и действие. Например, при неизвестной формуле команда сначала восстанавливает источник данных. При подтверждённом расходе и неясной причине уменьшает долю трафика для нового релиза и назначает разбор. При исчерпанном бюджете откладывает несрочный rollout, но отдельно рассматривает security fix или исправление причины с явным планом отката.
\nПрогрессивный rollout ограничивает blast radius, но не исправляет плохой SLI. На каждом этапе задайте длительность наблюдения, минимальный объём событий, критерий остановки и способ вернуть предыдущую версию. Ручное решение остаётся важным: одинаковый расход может означать известную деградацию, ошибку сбора или новую проблему после выкладки.
\nПосле действия повторите расчёт на той же популяции и в сопоставимом окне. Если процент улучшился только после удаления таймаутов из eligible, это не восстановление сервиса. Если причина устранена, а signal не изменился, проверяйте задержку доставки или гипотезу, а не подгоняйте denominator.
\nSLI показывает соответствие выбранному критерию, но не объясняет корневую причину. Он также не покрывает то, что не попало в scope: не дошедшие до backend запросы, неверный результат, отдельный регион или позднее событие. Для этих рисков нужны дополнительные сигналы и проверки. Несколько зелёных SLI не складываются автоматически в доказательство здоровья всей системы.
\nЧисловой пример не подключён к файлам, CI, мониторингу, сети, HTTP или реальной конфигурации. Он не создаёт alert, не меняет rollout и не разрешает выпуск. Google SRE описывает error budget как механизм совместного решения, но конкретные target, окно, page и исключения требуют согласования продуктового владельца, разработки и эксплуатации.
\nЕсли данных мало, задержка не известна или источник нельзя воспроизвести, правильный результат проверки — «решение отложено» либо «сигнал недостаточен», а не выдуманный инцидент. Если действие необратимо, сначала нужна дополнительная защита: staged rollout, snapshot, rollback или ручное подтверждение.
\nРазговор можно закрыть, когда другой инженер без устного контекста воспроизводит число и понимает действие. В записи есть пользовательский результат, версия формулы, eligible и good, target, окно, источник, владелец, критерий остановки, план отката и повторная проверка. Есть отрицательный пример, который текущий SLI не скрывает.
\nПеред релизом достаточно задать три вопроса: что именно измеряется, почему это покрывает нужный путь и что произойдёт при ухудшении. Если на первый вопрос отвечает только цвет графика, а на третий — «разберёмся по ситуации», SLO пока остаётся отчётной метрикой, а не рабочим договором.
\n