Files
progcode/editorial/agent-rewrites/152.json
T
huncode 2d914b543f
Build and deploy / deploy (push) Failing after 15s
Publish rewritten technical article archive
2026-08-02 22:19:34 +03:00

8 lines
16 KiB
JSON
Raw 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": 152,
"slug": "editorial-2023-10-mechanism-sli-slo",
"title": "Error budget без магии: как проверить SLI, окно и решение",
"excerpt": "Процент доступности не объясняет сам себя. Разбираем связь SLI, SLO и error budget: от пользовательского пути и знаменателя до проверки формулы, policy и безопасного действия.",
"contentHtml": "<p>На панели появляется красный процент. В релизном чате говорят: «бюджет почти закончился». Но никто не может быстро ответить, какой пользовательский путь измеряет график, какие события попали в знаменатель и когда началось окно. Один отчёт считает отменённый запрос, другой исключает его. Один смотрит последние 28 дней, другой — календарный месяц.</p>\n<p>Цена ошибки — не спор о терминах. Команда может остановить полезное исправление из-за неверной формулы. Или продолжить рискованный rollout, потому что неуспешные события не попали в расчёт. Красный цвет не становится решением, пока за ним нет проверяемого договора.</p>\n<h2>Тезис: budget начинается с границы измерения</h2>\n<p>SLI — это количественная мера конкретного свойства сервиса. SLO задаёт для этой меры цель или диапазон. Error budget — допустимая часть неуспешных событий внутри той же границы и того же окна. Если команда меняет scope, eligible-события, good-события, окно или target, она меняет модель. Старый процент больше нельзя сравнивать с новым без оговорки.</p>\n<p>Начинайте не с девяток. Сначала назовите действие пользователя. Для условного checkout это может быть «пользователь отправил заказ и получил подтверждение». Затем определите множество eligible-событий, правило успеха, исключения, окно, источник данных и владельца. Только после этого формула получает смысл.</p>\n<table><caption>Минимальный договор для SLI</caption><thead><tr><th scope='col'>Поле</th><th scope='col'>Пример</th><th scope='col'>Проверка</th></tr></thead><tbody><tr><td>Scope</td><td>checkout-submit</td><td>Событие относится к нужному пользовательскому пути</td></tr><tr><td>Eligible</td><td>завершённая попытка отправки</td><td>Знаменатель включает все случаи этой границы</td></tr><tr><td>Good</td><td>подтверждение получено в срок</td><td>Правило не зависит от цвета dashboard</td></tr><tr><td>Окно</td><td>rolling 28 days</td><td>Период одинаков в расчёте и обсуждении</td></tr><tr><td>Target</td><td>99,5%</td><td>Число связано с policy и владельцем</td></tr></tbody></table>\n<h2>Как работает арифметика</h2>\n<p>Учебный пример ниже не читает monitoring и не описывает production. В окне есть 1 000 eligible-событий. Из них 994 соответствуют правилу good. SLI равен 994 / 1 000 = 99,4%. При target 99,5% условный budget исчерпан: допустимая доля bad равна 0,5%, то есть пять событий, а фактическая — шесть.</p>\n<pre><code>const eligible = 1000; const good = 994; const target = 0.995; const sli = good / eligible; const allowedBad = eligible * (1 - target); const actualBad = eligible - good; console.log({ sli, allowedBad, actualBad, budgetExhausted: actualBad &gt; allowedBad }); // учебный результат: { sli: 0.994, allowedBad: 5, actualBad: 6, budgetExhausted: true }</code></pre>\n<p>Числа в коде намеренно synthetic. Они не доказывают доступность, burn rate, incident или стоимость простоя. В рабочей системе нужно подтвердить, откуда пришло каждое событие и почему оно относится к scope. Формула без этого лишь аккуратно делит неизвестные данные.</p>\n<p>Есть и отрицательный путь. Если знаменатель равен нулю, процент нельзя объявлять равным 100%. Если good больше eligible, источник или преобразование сломаны. Если сервис измеряет только HTTP-ответ, а пользовательская ценность появляется после фоновой обработки, SLI может быть полезным proxy, но не прямым измерением результата. Proxy gap надо назвать явно.</p>\n<h2>Окно не лечит плохой знаменатель</h2>\n<p>Rolling window показывает недавнее состояние и постепенно вытесняет старые события. Fixed window проще связать с отчётным периодом. Ни один режим не исправляет ошибку в eligible set. При малом трафике одна ошибка резко меняет процент. При большом трафике среднее может скрыть хвост задержки. Для latency среднее также может быть слишком грубым: несколько очень медленных запросов исчезнут в общей цифре.</p>\n<p>Окно нужно записать рядом с формулой, а не оставить подписью графика. При смене 28 дней на 30 дней, при смене fixed на rolling или при изменении часового пояса меняется сравнение. Пересчитайте исторические значения либо пометьте границу новой версией договора.</p>\n<h2>Симптом → причина → проверка → действие</h2>\n<div class='table-scroll'><table><caption>Диагностическая матрица для SLI/SLO</caption><thead><tr><th scope='col'>Симптом</th><th scope='col'>Причина</th><th scope='col'>Проверка</th><th scope='col'>Действие</th></tr></thead><tbody><tr><td>Два отчёта показывают разные SLI</td><td>Разные scope или exclusions</td><td>Сравнить определения eligible и good на трёх одинаковых событиях</td><td>Версионировать один контракт и убрать скрытый фильтр</td></tr><tr><td>Процент равен 100% при отсутствии трафика</td><td>Нулевой знаменатель превращён в успех</td><td>Проверить обработку пустого окна</td><td>Вернуть состояние no-data и отдельное правило для него</td></tr><tr><td>Красный budget не связан с жалобами</td><td>SLI измеряет proxy или не тот путь</td><td>Сопоставить событие метрики с user journey</td><td>Сузить scope либо добавить пользовательский сигнал</td></tr><tr><td>После смены окна исчезла деградация</td><td>Сравнили несовместимые периоды</td><td>Проверить версию окна и границы timestamp</td><td>Пересчитать историю или явно разделить серии</td></tr><tr><td>Budget требует немедленной блокировки</td><td>Нет policy и проверки контекста</td><td>Назвать owner, обратимость и тип изменения</td><td>Выбрать review, rollback, сужение rollout или продолжение с контролем</td></tr></tbody></table></div>\n<figure><img src='/assets/editorial/2023/slo-error-budget-2023-budget-window.svg' alt='Связь SLI-контракта, окна и error budget: scope задаёт eligible-события, good-события формируют SLI, target задаёт допустимый budget, а policy определяет действие.' loading='lazy' /><figcaption>Механизм начинается с границы события. Процент появляется после определения scope, eligible, good, окна и target. Policy связывает результат с ручным решением; сама арифметика не выдаёт право блокировать релиз.</figcaption></figure>\n<h2>Budget не является автоматическим gate</h2>\n<p>Расход бюджета — сигнал для принятия решения, а не универсальная команда остановить deploy. Policy должна назвать владельца, обязательные evidence, допустимые действия и исключения. Security fix может потребовать другого пути согласования. Обратимый rollout может потребовать сужения exposure. Неверный расчёт требует остановить интерпретацию метрики, а не обязательно остановить весь релиз.</p>\n<p>Отдельно разделяйте SLI и диагностику. SLI отвечает на вопрос, нарушается ли выбранная мера. Логи, трассы, версии, очереди и зависимости помогают искать причину. Один сигнал не обязан объяснять другой. Если после красного процента команда сразу объявляет incident, она пропускает проверку scope, времени и источника данных.</p>\n<h2>Порядок проверки</h2>\n<ol><li><strong>Зафиксируйте симптом.</strong> Сохраните значение, timestamp, версию SLI-контракта и точный user journey. Не меняйте формулу во время расследования.</li><li><strong>Проверьте границу.</strong> Для одного good, одного bad и одного спорного события определите, попадает ли каждое в eligible и почему.</li><li><strong>Пересчитайте малую выборку.</strong> Сравните ручной подсчёт с запросом или exporter. Отдельно проверьте нулевой знаменатель и ошибочное превышение good над eligible.</li><li><strong>Проверьте окно.</strong> Сверьте начало, конец, timezone, fixed или rolling режим и задержку доставки событий.</li><li><strong>Отделите proxy от результата.</strong> Проверьте, измеряет ли событие ценность пользователя или только слой системы. Запишите расхождение.</li><li><strong>Примените policy.</strong> Назначьте owner и выберите обратимое действие: исправить источник, сузить rollout, отложить non-urgent изменение или продолжить с контролем.</li><li><strong>Повторите расчёт.</strong> Используйте ту же формулу и тот же критерий. Если сигнал не изменился ожидаемым образом, вернитесь к гипотезе.</li></ol>\n<h2>Ограничения</h2>\n<p>SLI не измеряет всё качество продукта. Доступность backend не гарантирует успешный пользовательский сценарий. Error budget не показывает корневую причину и не определяет важность изменения. Target 99,5% и окно 28 дней в примере не являются рекомендацией. Для редкого трафика, пакетной обработки, долгих операций и юридического SLA нужны отдельные решения.</p>\n<p>Учебный код также не создаёт alert, не читает реальные события, не меняет CI и не принимает решение о выпуске. Его можно использовать для проверки арифметики и отрицательных веток. Production-вывод появляется только после проверки источника данных, владельца, разрешений и поведения системы на реальном трафике.</p>\n<h2>Критерий готовности</h2>\n<p>Договор готов, если инженер за несколько минут может показать scope, eligible, good, exclusions, окно, target, источник, owner и policy branch. Для трёх выбранных событий два инженера получают одинаковый ответ. Пустое окно не становится успешным автоматически. После действия та же версия формулы даёт ожидаемое изменение, а новое значение можно связать с timestamp и источником.</p>\n<p>Если хотя бы одно поле неизвестно, статус должен быть «договор не готов». Не добавляйте ещё один график поверх неопределённости. Сначала восстановите границу измерения, затем решайте, какое действие безопасно.</p>\n<h2>Проверяемые источники</h2>\n<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 как цели или диапазона; источник также отмечает, что серверная мера иногда является proxy пользовательского опыта.</li><li><a href='https://sre.google/workbook/slo-document/' target='_blank' rel='noopener noreferrer'>Google SRE Workbook: Example SLO Document</a> — официальный пример структуры SLO-документа со scope, SLI, SLO и окном измерения. Это пример формы, а не готовое окно для любого сервиса.</li><li><a href='https://sre.google/workbook/error-budget-policy/' target='_blank' rel='noopener noreferrer'>Google SRE Workbook: Error Budget Policy</a> — официальный пример связи error budget с правилами приоритизации и действиями команды. Он не даёт автоматического права блокировать конкретный релиз.</li></ul>"
}