DarkRiDDeR12 мин

SLI/SLO в релизном разговоре: бюджет как петля решения, не как красный график

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

Проблема релизного дня редко звучит технически чисто. На панели красный блок, кто-то говорит «бюджет почти закончился», другая команда просит не задерживать изменение, а on-call не может объяснить, какой пользовательский путь пострадал. Если принять решение только по цвету, можно остановить безопасное исправление или выпустить изменение в момент, когда полезнее сначала разобраться с надёжностью. Цена — не только риск для пользователя. Команда привыкает считать SLO отчётностью, потому что число не связывается с действием и ответственностью.

Обратная ошибка — превратить budget в автоматический запрет. Формула сама не знает, является ли изменение обратимым, закрывает ли оно security-уязвимость, относится ли к тому же пути и подтверждены ли входные данные. Без policy владелец узнаёт о решении уже после того, как CI или чей-то скрипт сделал необратимое действие. Цена — скрытые полномочия и плохая диагностика: красный график объясняет «что-то не так», но не показывает причину, границу или следующий безопасный шаг.

Error budget нужен для вопроса, а не для победы в споре

Google SRE Book в главе 2017 года описывает error budget как способ обсудить допустимый риск между разработкой и надёжностью. В Example Error Budget Policy Google SRE Workbook от 19 февраля 2018 года отдельно сказано, что policy не является наказанием за missed SLO. Практический смысл для небольшой команды: заранее договориться, какое evidence нужно перед решением и какие обратимые действия допустимы. Тогда цифра не заканчивает разговор; она запускает один и тот же маршрут для релиза, reliability-задачи и разбора расхождения.

Это особенно важно, когда SLI — proxy. Низкая доля good событий может относиться к одному backend-ответу, но не объяснять весь пользовательский путь. Высокая доля может скрывать ошибку после точки измерения. Поэтому петля решения содержит два разных перехода: сначала проверить, что сигнал соответствует договору, затем искать причину в разрешённых данных. Нельзя перепрыгнуть из одного synthetic процента к выводу «был инцидент» или «нужно заблокировать production». Эти утверждения требуют других фактов и других владельцев.

Запись для решения вместо одного цвета
ШагЧто должен принести ownerДопустимое действиеЧего не делает шаг
Сигналверсия SLI-contract, scope, окно, target и time of observationоткрыть разборне объявляет incident автоматически
Проверка формулыeligible/good definitions, exclusions и источникостановить неверный расчётне доказывает причину деградации
Контекстдиагностические данные разрешённой среды и known changesсформировать гипотезуне подменяет продуктовый impact
Решениеowner, policy, обратимость и evidenceсузить rollout, исправить, отложить или продолжить с контролемне выдаёт CI-право учебному fixture
Повторная проверката же формула и критерий после действияподтвердить или пересмотреть гипотезуне обещает отсутствие следующих сбоев
Петля решения: synthetic сигнал сверяется с SLI-контрактом, затем в разрешённой среде ищется контекст; owner выбирает обратимое действие и повторную проверку. У стрелки к релизу стоит ручное решение, а не автоматический gate.
Схема не является журналом инцидента, CI pipeline или мониторингом. Она не получает реальные SLI, availability, burn rate или данные о выпуске.

Один сигнал не объясняет причину

SLI отвечает на заранее узкий вопрос: выполняется ли выбранная мера в выбранной границе. Он не обязан хранить корневую причину. Когда сигнал отклоняется, следующей задачей становится диагностика: изменение версии, зависимость, класс ответов, очередь, лимит, данные или сценарий клиента. Набор диагностических сигналов зависит от архитектуры и доступа. Нельзя заранее объявить, что trace, log или dashboard всегда дадут ответ. Но можно заранее назначить, кто проверяет scope и кто подтверждает, что данные относятся к одному и тому же периоду.

В Google SRE Workbook 2018 о SLO alerting подчёркнута разница между alerting metric и данными, которые помогают расследовать причину. Этот вывод не позволяет сказать «любая красная точка требует page». Он учит не смешивать роль меры и роль объяснения. Для одних путей нужен срочный response, для других — ticket, review или временное ограничение rollout. Сначала должна быть policy с владельцем и уровнями действий, а затем выбранные thresholds. Без этого alert просто переносит спор из чата в notification channel.

Policy должна быть короткой и исполнимой людьми

Минимальная policy помещается в несколько строк: какие SLO относятся к релизу, кто владелец решения, какие данные обязательны, что считается обратимым действием, какие исключения требуют отдельного одобрения и когда договор пересматривают. Важно указать не только «при exhausted budget остановить изменения», но и что именно означает exhausted по версии формулы, какая проверка защищает от ложного сигнала и кто может разрешить security fix. Иначе правило будет жить только в памяти того, кто однажды настроил дашборд.

Synthetic fixture оставляет полномочие у владельца

Здесь fixture специально не играет роль release gate. Он возвращает `proposal`, но всегда сохраняет `releaseAuthority=not-granted`. В хорошей synthetic ветке остаётся четыре условные единицы бюджета, поэтому proposal — review before change. В другой ветке условный budget exhausted, но это всё равно не incident и не команда остановить реальную выкладку. Fixture не видит code diff, security context, CI result, feature flag, owner approval или production traffic; выдавать ему полномочие было бы ошибкой модели.

import { runSloFixture } from './upgrade-2023-10.mjs';

const report = runSloFixture();
if (!Object.values(report.assertions).every(Boolean)) throw new Error('fixture failed');

console.log(report.samples.valid.decision.releaseAuthority); // not-granted
console.log(report.samples.valid.calculation.observed); // not-observed

// Полный synthetic вход и отрицательные ветки находятся в этом же модуле.
// Нет чтения проекта, monitoring, CI, сети, real SLI, incident, burn rate или availability.

node web/scripts/upgrade-2023-10.mjs --verify-fixture

# PASS подтверждает только согласованность synthetic договора и его отрицательных веток.

Запуск создаёт фиксированные JS-объекты в памяти и завершается. Он не читает проект, не вызывает monitoring, CI, сеть, HTTP, SDK или часы. У него нет реальных SLI, availability, incident, burn rate, event stream либо dashboard. Даже отрицательная ветка `synthetic-reliability-work-first` описывает только ожидаемую форму учебной развилки. PASS проверяет, что она не перепутана с разрешением на release, а не то, что какой-либо сервис достиг цели.

Маршрут: симптом → причина → проверка → действие

  1. Симптом. Релизная команда видит красный budget-показатель, но не может связать его с конкретным путём, окном и версией SLI-contract.
  2. Причина. Сигнал, формула, диагностические данные и policy развивались отдельно; график получил вес решения, но не получил owner и границы полномочий.
  3. Проверка формулы. Сверьте scope, good/eligible events, exclusions, окно, target и источник. Если версия правила неизвестна, остановите интерпретацию, а не релиз по умолчанию.
  4. Проверка контекста. В разрешённой среде соберите минимальные данные для одной гипотезы и отделите их от synthetic fixture. Не называйте correlation или событие доказанными, пока источник не подтверждён.
  5. Действие. Owner выбирает обратимый шаг согласно policy: сузить exposure, исправить причину, отложить non-urgent change или продолжить с явным контролем. Выбор фиксируется вместе с evidence.
  6. Повтор. После действия примените ту же версию формулы и проверьте известный критерий. При расхождении пересматривайте гипотезу, а не подгоняйте denominator.

План обратного действия должен предшествовать спору

Слова «если что, откатим» не являются policy. До изменения нужно назвать, что именно меняется: код, конфигурация, правило обработки или ограничение exposure. Затем — какую версию вернуть, кто это сделает, что будет считаться подтверждением и какие потребители затронуты. Если действие нельзя обратить, policy должна сказать это прямо и потребовать иной уровень review. Error budget полезен тем, что превращает такое обсуждение в ожидаемую часть работы, а не в реакцию на громкий график.

Учебный rollback нарочно скучный: он возвращает пять полей synthetic договора и говорит, что monitoring, CI и сеть не затронуты. Он не может остановить deploy или удалить записи, потому что ничего такого не создавал. В реальной системе это ограничение не повод делать вид, что rollback существует. Это повод вынести операционный план в отдельный runbook с теми системами, где у команды действительно есть права и наблюдение.

Ограничения и следующий шаг

Пакет не показывает production incident, доступность, SLI, burn rate, error budget, алерт, CI run, релиз, пользователя или стоимость. Он не читает проект и не обращается к monitoring, CI, сети, HTTP, SDK, clock или dashboard. Все имена, события, количества и состояния имеют synthetic marker и существуют только в памяти Node. Google-источники задают исторические определения и примеры policy, но не предоставляют автоматический gate и не дают этому fixture права оценивать реальный риск.

Следующий шаг для команды — сделать одну реальную decision record до следующего спорного изменения. В ней должны быть SLI-contract version, owner, scope, источник evidence, окно, target, policy branch, обратимое действие и повторная проверка. Если не хватает хотя бы одной строки, не скрывайте пробел новой визуализацией. Сначала назначьте владельца и сузьте вопрос. Тогда SLO перестанет быть декорацией и станет способом честно выбрать следующий инженерный шаг.

Историческая граница октября 2023

К октябрю 2023 уже были доступны Google SRE Book 2017 и Google SRE Workbook 2018 с примерами SLO document, error budget policy и SLO alerting. Статья опирается на эти документы, не добавляя поздние платформенные практики и не имитируя чужую production-историю. Автор уровня M6 здесь связывает измерение с owner, evidence и обратимостью, но не выдаёт учебную модель за статистику своей системы.

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

  • Google SRE Book: Service Level Objectives, copyright 2017 — Первичный материал Google SRE: определяет SLI как количественную меру, SLO как целевое значение или диапазон и связывает error budget с решением о риске. Он не задаёт порог, окно, формулу или владельца для конкретного проекта.
  • Google SRE Workbook: Example SLO Document, 19.02.2018 — Официальный пример документа с датой 19.02.2018: в нём есть scope, SLI, SLO и четырёхнедельное rolling window. Это пример формы, а не обязательное окно для любого сервиса.
  • Google SRE Workbook: Example Error Budget Policy, 19.02.2018 — Официальный пример policy: расход бюджета служит правилом приоритизации и не должен быть наказанием. Он не разрешает автоматически блокировать или выпускать чужие изменения.
  • Google SRE Workbook: Alerting on SLOs, copyright 2018 — Официальная глава о том, что alert должен относиться к действенной угрозе бюджету; отдельно разбираются ограничения low-traffic систем. Она не подтверждает реальный burn rate, alert или incident этого учебного пакета.