Files

8 lines
20 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"index": 151,
"slug": "editorial-2023-10-field-sli-slo",
"title": "SLI/SLO в релизном разговоре: от красного графика к проверяемому решению",
"excerpt": "Как связать SLI, SLO и error budget с пользовательским путём, окном измерения и обратимым действием — и не выдать один график за доказательство инцидента или автоматический запрет релиза.",
"contentHtml": "<p>На релизе график error budget становится красным. Один инженер предлагает остановить выкладку, другой просит не задерживать исправление. Но никто не может сразу ответить, какой пользовательский путь измеряет график, какие события входят в знаменатель и за какое окно посчитан расход. В итоге команда обсуждает цвет панели вместо проверяемого факта.</p>\n<p>Ошибка в такой ситуации стоит дорого в обе стороны. Слабый SLI может оставить сломанным путь, который сервер формально считает успешным. Нечёткая policy может остановить безопасное изменение из-за одного нерепрезентативного всплеска. Поэтому SLO полезен не как печать «можно» или «нельзя», а как часть петли: измерили, сравнили с целью, проверили контекст, выбрали действие, повторили измерение.</p>\n<p>Ниже — практический способ провести этот разговор. Сначала зафиксируем контракт показателя, затем разберём знаменатель и окно, после чего превратим расход бюджета в ограниченное и обратимое решение. Все числа в примерах учебные: они показывают арифметику и порядок проверки, но не описывают конкретную production-систему.</p>\n<h2>Что именно измеряют SLI, SLO и error budget</h2>\n<p>SLI (service level indicator) — количественная мера свойства сервиса: например, доля успешных запросов или доля запросов, завершившихся быстрее порога. SLO (service level objective) — целевое значение SLI при явно названных условиях. Error budget — допустимая часть неуспеха за то же окно. Для цели 99% это 1% событий, которые могут не соответствовать критерию, если договор считает их одинаково.</p>\n<p>Минимальный контракт должен назвать пользовательский scope, способ измерения, eligible-события, good-события, target и window. Scope говорит, какой результат защищаем. Eligible задаёт знаменатель. Good задаёт числитель. Window задаёт период, в котором результат сравнивают с целью. Policy добавляет владельца и действие, но не меняет саму формулу.</p>\n<pre><code>eligible = 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# Учебные числа: здесь нет источника событий и реального окна.</code></pre>\n<p>В учебной модели осталось место ещё для четырёх неуспешных событий до цели 99%. Это не означает, что сервис «на 99,4% надёжен» во всех смыслах: код 202 может лишь поставить операцию в очередь, а клиентский JavaScript может сломаться после ответа API. Если изменить exclusions, источник или границу завершения, изменятся eligible и good, а вместе с ними — весь вывод.</p>\n<h2>Сначала назовите пользовательский результат</h2>\n<p>Серверная метрика удобна, но удобство не делает её пользовательским SLI. Запрос «создать заказ» может получить 202, а очередь позднее отклонит заказ. Или backend ответит за 80 мс, пока браузер ждёт загрузки скрипта и не показывает подтверждение. Такой backend-SLI честно описывает свою точку измерения, но не весь путь.</p>\n<p>Формулировка должна начинаться с действия: «пользователь отправляет заказ и видит подтверждение». Затем задайте границу завершения: получение 202, появление записи в заказах или видимый экран подтверждения. Выберите источник, который действительно видит эту границу: серверный лог, black-box проверка или клиентская телеметрия. У каждого способа своя цена покрытия и сопровождения.</p>\n<p>Не смешивайте спецификацию и реализацию. Спецификация может звучать как «доля заказов, подтверждённых не позднее пяти минут». Реализация через лог API не увидит отказы до backend; реализация через браузерный synthetic-проверяющий охватит доступность пути, но может не отражать всех клиентов. В договоре нужно записать, какой пробел принят и зачем.</p>\n<figure><img src=\"/assets/editorial/2023/slo-error-budget-2023-decision-loop.svg\" alt=\"Петля решения SLI/SLO: сигнал проходит проверку контракта и контекста, затем владелец выбирает обратимое действие и повторную проверку\" loading=\"lazy\" /><figcaption>Схема показывает порядок разговора: сигнал не равен причине, а расход бюджета не является автоматическим релизным gate. Это учебная диаграмма, а не мониторинг или журнал инцидента.</figcaption></figure>\n<h2>Знаменатель и окно могут перевернуть вывод</h2>\n<p>Eligible — не «все записи, которые удобно посчитать», а заранее определённая популяция. Таймауты, повторные попытки, отмены и некорректные входы нельзя молча выкинуть только потому, что они ухудшают процент. Если событие исключается, запишите техническую причину, владельца правила и отрицательный пример. Иначе команда улучшает отчёт, меняя объект измерения.</p>\n<p>Окно тоже часть контракта. Скользящее окно сохраняет недавний сбой в расчёте и не обнуляет его в начале календарного месяца. Календарное окно удобнее для отчётности и планирования, но посреди периода сложнее оценить, сколько трафика ещё поступит. Для обоих вариантов укажите часовой пояс, границы, задержку событий и правило пересчёта.</p>\n<p>На малом трафике один отказ заметно меняет ratio. Это не запрет на SLO, а причина не строить срочный автоматический вывод на малой выборке. Можно увеличить окно, поднять минимальное число eligible-событий для page или отправлять такой сигнал в ticket на ручной разбор. Порог реакции выбирается вместе с формулой, а не после неё.</p>\n<table><caption>Карта разбора красного или зелёного сигнала</caption><thead><tr><th scope=\"col\">Наблюдение</th><th scope=\"col\">Возможная причина</th><th scope=\"col\">Проверяем</th><th scope=\"col\">Следующее действие</th></tr></thead><tbody><tr><td>Красный budget, но неизвестна формула</td><td>Смешаны окно, exclusions или версия запроса</td><td>Сверяем SLI-контракт и исходные выборки</td><td>Не принимать релизное решение до восстановления evidence</td></tr><tr><td>Команды получили разные проценты</td><td>Разные eligible, good или часовой пояс</td><td>Сравниваем запрос, период, фильтры и повторные попытки</td><td>Назначаем владельца одной версии расчёта</td></tr><tr><td>Зелёный SLI, но путь не работает</td><td>Точка измерения раньше пользовательского результата</td><td>Проходим сценарий до подтверждения</td><td>Расширяем scope или добавляем отдельный клиентский SLI</td></tr><tr><td>Один отказ сильно изменил процент</td><td>Малое окно или низкий трафик</td><td>Считаем объём и распределение событий</td><td>Меняем окно или переводим сигнал в ручной разбор</td></tr><tr><td>Красный график блокирует любой релиз</td><td>Policy не различает срочность и обратимость</td><td>Проверяем blast radius, rollback и тип изменения</td><td>Сужаем rollout, откатываемся или продолжаем с контролем</td></tr></tbody></table>\n<h2>Как превратить budget в решение о rollout</h2>\n<p>Policy — это не фраза «при красном остановить всё». В ней должны быть условие, evidence, владелец и действие. Например, при неизвестной формуле команда сначала восстанавливает источник данных. При подтверждённом расходе и неясной причине уменьшает долю трафика для нового релиза и назначает разбор. При исчерпанном бюджете откладывает несрочный rollout, но отдельно рассматривает security fix или исправление причины с явным планом отката.</p>\n<p>Прогрессивный rollout ограничивает blast radius, но не исправляет плохой SLI. На каждом этапе задайте длительность наблюдения, минимальный объём событий, критерий остановки и способ вернуть предыдущую версию. Ручное решение остаётся важным: одинаковый расход может означать известную деградацию, ошибку сбора или новую проблему после выкладки.</p>\n<p>После действия повторите расчёт на той же популяции и в сопоставимом окне. Если процент улучшился только после удаления таймаутов из eligible, это не восстановление сервиса. Если причина устранена, а signal не изменился, проверяйте задержку доставки или гипотезу, а не подгоняйте denominator.</p>\n<h2>Воспроизводимый порядок проверки</h2>\n<ol><li><strong>Назовите путь.</strong> Запишите действие пользователя, ожидаемый результат, симптом и цену ошибочного решения.</li><li><strong>Зафиксируйте контракт.</strong> Укажите scope, источник, eligible, good, exclusions, target, окно, часовой пояс и задержку поступления данных.</li><li><strong>Пересчитайте малую выборку.</strong> Возьмите несколько успехов и отказов, вручную проверьте классификацию и сохраните отрицательный пример. Сверьте результат с формулой из статьи.</li><li><strong>Проверьте реализацию.</strong> Сопоставьте логи, метрики, synthetic или клиентскую телеметрию с одной операцией и одной версией. Не называйте корреляцию причиной.</li><li><strong>Оцените решение.</strong> Проверьте объём трафика, срочность, обратимость и blast radius. Выберите pause, узкий rollout, rollback, исправление или продолжение с наблюдением по policy.</li><li><strong>Назначьте владельца.</strong> Запишите, кто выполняет действие, в какой момент и каким наблюдением подтверждается результат.</li><li><strong>Повторите без смены правил.</strong> Пересчитайте тот же SLI после изменения. Отдельно отметьте, что осталось вне покрытия.</li></ol>\n<h2>Ограничения и отрицательные случаи</h2>\n<p>SLI показывает соответствие выбранному критерию, но не объясняет корневую причину. Он также не покрывает то, что не попало в scope: не дошедшие до backend запросы, неверный результат, отдельный регион или позднее событие. Для этих рисков нужны дополнительные сигналы и проверки. Несколько зелёных SLI не складываются автоматически в доказательство здоровья всей системы.</p>\n<p>Числовой пример не подключён к файлам, CI, мониторингу, сети, HTTP или реальной конфигурации. Он не создаёт alert, не меняет rollout и не разрешает выпуск. Google SRE описывает error budget как механизм совместного решения, но конкретные target, окно, page и исключения требуют согласования продуктового владельца, разработки и эксплуатации.</p>\n<p>Если данных мало, задержка не известна или источник нельзя воспроизвести, правильный результат проверки — «решение отложено» либо «сигнал недостаточен», а не выдуманный инцидент. Если действие необратимо, сначала нужна дополнительная защита: staged rollout, snapshot, rollback или ручное подтверждение.</p>\n<h2>Критерий готовности к релизному решению</h2>\n<p>Разговор можно закрыть, когда другой инженер без устного контекста воспроизводит число и понимает действие. В записи есть пользовательский результат, версия формулы, eligible и good, target, окно, источник, владелец, критерий остановки, план отката и повторная проверка. Есть отрицательный пример, который текущий SLI не скрывает.</p>\n<p>Перед релизом достаточно задать три вопроса: что именно измеряется, почему это покрывает нужный путь и что произойдёт при ухудшении. Если на первый вопрос отвечает только цвет графика, а на третий — «разберёмся по ситуации», SLO пока остаётся отчётной метрикой, а не рабочим договором.</p>\n<h2>Проверяемые источники</h2><ul><li><a href=\"https://sre.google/sre-book/service-level-objectives/\" target=\"_blank\" rel=\"noopener noreferrer\">Google SRE Book: Service Level Objectives</a> — официальное объяснение SLI, SLO, пользовательских показателей, агрегации и error budget; параметры из статьи не выдаются за рекомендации для конкретного сервиса.</li><li><a href=\"https://sre.google/sre-book/service-best-practices/\" target=\"_blank\" rel=\"noopener noreferrer\">Google SRE Book: A Collection of Best Practices for Production Services</a> — официальные рекомендации измерять сервис с точки зрения пользователя, использовать error budget и наблюдать staged rollout с возможностью отката.</li><li><a href=\"https://sre.google/workbook/implementing-slos/\" target=\"_blank\" rel=\"noopener noreferrer\">Google SRE Workbook: Implementing SLOs</a> — официальный пошаговый материал о выборе SLI, rolling или calendar window, согласовании владельцев и error budget policy.</li></ul>"
}