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

Когда нагрузка растёт, бюджет ошибок сгорает быстрее, чем кажется
Сервис с SLO 99,9% может выглядеть надёжным на графике за месяц и при этом за несколько минут потерять значительную часть бюджета ошибок. Причина — перегрузка редко превращается в равномерный поток независимых сбоев: сначала накапливается очередь, затем растёт задержка, клиенты получают таймауты и повторяют запросы, а повторные попытки добавляют нагрузку в систему, которая уже не справляется.
Поэтому вопрос не только в том, сколько ошибок разрешает SLO. Важно понять, что именно вы считаете плохим событием, где возникает первое ограничение и как оно меняет поведение остальных компонентов. Ниже — разбор для инженеров, которые отвечают за работающий сервис, а не за красивую цифру в отчёте.
Что именно считает бюджет ошибок
SLO задаёт целевой уровень качества за выбранное окно. Например, если цель — 99,9% успешных запросов за 30 дней, допустимая доля плохих событий составляет 0,1%. Если учитываются все запросы, бюджет — 0,1% от их числа за это окно. Это не обязательно означает, что сервис может быть недоступен 0,1% времени: так получится только при временном SLI, где качество оценивают по интервалам, а не по запросам.
SLI* — измеряемый показатель качества, например доля запросов, завершившихся успешно и быстрее установленного порога. Бюджет зависит от формулировки SLI: ошибка HTTP, таймаут, ответ с неверными данными и слишком медленный ответ могут учитываться по-разному. Если медленные ответы не входят в SLI, система может формально выполнять SLO, пока пользователи уже ждут неприемлемо долго.
Прежде чем смотреть на нагрузочный тест, зафиксируйте четыре условия:
- какие запросы входят в расчёт, а какие исключены;
- что считается плохим событием: ошибка, задержка выше порога или оба случая;
- какой используется знаменатель — запросы, сессии, интервалы времени;
- как долго длится окно SLO и как быстро команда должна заметить расход бюджета.
Особенно опасен знаменатель, который меняется вместе с нагрузкой. Если считать ошибки только среди запросов, дошедших до приложения, отказы на балансировщике могут выпасть из SLI. А если считать только ответы приложения, клиенты, которые вообще не дождались ответа, могут исчезнуть из расчёта. Измерять стоит то, что действительно испытывает пользователь, с учётом границ системы.
Цепочка отказа: от очереди до лавины повторов
Под нагрузкой первым обычно проявляется не «падение сервера», а рост времени ожидания. Когда поступающие запросы обрабатываются медленнее, чем приходят, они копятся в очереди. Время ответа растёт, а вместе с ним — вероятность таймаута на клиенте, прокси или внутри приложения. Конкретный первый ограничитель зависит от архитектуры: это может быть пул соединений, CPU, хранилище, внешний API или слишком узкая очередь.
Как нагрузка превращается в расход бюджета
- Появляется насыщение. Один ресурс приближается к пределу: заняты рабочие потоки, исчерпан пул соединений, растёт очередь задач. Средняя загрузка может скрыть проблему, поэтому смотрите и на хвосты распределения, например p95 и p99 задержки.
- Растёт время ожидания. Запросы дольше занимают ресурсы, и пропускная способность падает. Если SLI включает порог задержки, бюджет начинает уходить ещё до появления явных 5xx.
- Срабатывают таймауты и повторы. Клиент не знает, завершилась ли операция, и отправляет запрос снова. Повтор может оказаться лишним: первый запрос всё ещё выполняется.
- Нагрузка усиливает сама себя. Повторные запросы занимают те же ресурсы, что и исходные. Очередь растёт быстрее, а зависимые сервисы получают больше работы.
- Отказывают соседние компоненты. Перегрузка уходит по цепочке: например, приложение удерживает соединения с базой, а база обрабатывает запросы дольше обычного.
Это типичный сценарий, а не универсальный порядок. Если внешний сервис ограничивает частоту запросов, первым сигналом может стать его ответ об отказе. Если приложение не ограничивает очередь, оно может продолжать принимать работу и исчерпать память. Вывод делайте по телеметрии конкретной системы, а не по одному графику CPU.
Бюджет ошибок — не запас на случай одной аварии. Это мера того, насколько быстро система превращает ухудшение одного компонента в плохой пользовательский опыт.
Что измерять в нагрузочном тесте
Для разбора под нагрузкой нужны не только итоговая доля ошибок и среднее время ответа. Собирайте временные ряды с одинаковыми временными метками и разделяйте данные по маршрутам или типам операций: общий показатель может скрыть, что один критичный путь уже деградировал.
- SLI и расход бюджета: доля плохих событий в окне и скорость её изменения. Для запроса, который длится дольше порога, учитывайте его в SLI так же, как ошибочный ответ, если это соответствует вашему определению.
- Задержка: p50, p95 и p99 по отдельным операциям. Среднее значение не показывает редкие, но болезненные для пользователя задержки.
- Пропускная способность и очередь: входящие и успешно обработанные запросы, число ожидающих задач, возраст самой старой задачи. Важно видеть, растёт ли очередь при постоянной нагрузке.
- Насыщение ресурсов: занятость потоков и соединений, память, CPU, ожидание дисковых операций, ограничения внешних сервисов. Измеряйте доступную ёмкость, а не только процент использования.
- Повторы и таймауты: долю запросов, выполненных повторно, их число на исходную операцию и места, где срабатывает таймаут. Иначе усиление нагрузки может выглядеть как внезапный рост клиентского трафика.
Запускайте тест ступенями: увеличивайте интенсивность, удерживайте каждую ступень достаточно долго, чтобы увидеть рост очередей, и фиксируйте момент, когда хвостовая задержка или доля плохих событий начинают ускоряться. После выхода на предел не продолжайте бесконтрольно наращивать поток: цель — найти форму деградации и ограничитель, а не просто получить максимальное число запросов в секунду.
Как определить, что ломается первым
Сопоставьте на одной временной шкале входящую нагрузку, успешную пропускную способность, задержки, очередь, таймауты и метрики зависимостей. Первым кандидатом на узкое место будет не обязательно компонент с самым высоким процентом загрузки. Ищите раннее изменение, которое предшествует росту ошибок: например, сначала перестают освобождаться соединения, затем растёт ожидание запросов к базе, а после — p99 и таймауты приложения.
Проверьте и обратную причинность. Рост таймаутов может быть следствием медленного хранилища, но может и сам ухудшать ситуацию, если клиенты повторяют запросы. Для проверки сравните тест с повторами и без них, не меняя остальные условия. Отдельно оцените, защищена ли система от перегруза: есть ли предел очереди, ограничение параллелизма и понятное поведение при отказе. Это не готовый рецепт настройки — значения следует выбирать по измерениям и требованиям конкретного сервиса.
Не смешивайте тестовую нагрузку и пользовательские события в одном итоговом выводе. Запишите версию приложения и конфигурацию, профиль трафика, длительность ступеней, объём данных и параметры окружения. Если нет достоверного замера «до», не придумывайте его: зафиксируйте исходную точку сейчас, а сравнение проводите после одного контролируемого изменения.
Граничные случаи: где выводы теста ломаются
- Тест не похож на реальный трафик. Равномерный поток не воспроизводит короткие всплески, популярные ключи или редкие тяжёлые операции. Проверьте отдельно пиковый профиль и распределение запросов.
- Тестовая база слишком маленькая. Индексы, кэш и рабочий набор данных ведут себя иначе, чем на проде. Сверьте размер и характер данных, а не только число записей.
- Считаются только ответы приложения. Отброшенные до приложения запросы могут не попасть в SLI. Сравните клиентскую телеметрию, балансировщик и серверные метрики.
- Повторы скрывают первоначальный отказ. Клиент в итоге получает успех, но система тратит на операцию больше ресурсов и может ухудшить задержку соседних запросов. Считайте исходные операции и попытки отдельно.
- Единичный тест приняли за гарантию. Результат зависит от версии приложения, окружения и состава трафика. Повторите проверку после значимых изменений и не переносите цифры на другую конфигурацию без проверки.
Что делать дальше
Сначала проверьте определение SLI: отражает ли оно результат, который видит пользователь, и учитывает ли медленные ответы. Затем выберите один критичный пользовательский путь, проведите ступенчатый тест и найдите метрику, которая меняется раньше остальных. После этого проверьте, как система ведёт себя при ограничении очереди и отключённых повторах. Такой план даст не абстрактный «предел сервиса», а конкретное понимание, где начинается деградация и какой сигнал нужно отслеживать в проде.
Сноска. Хвостовая задержка — задержка в верхней части распределения запросов; например, p99 означает, что 99% измеренных запросов завершились не медленнее этого значения, а оставшийся 1% занял больше времени.
Тест и проверочная: Быстрые ответы с объяснением, почему остальные варианты неверны
Спросить за 10 ₽Источники: Google SRE Book: Service Level Objectives, Google SRE Book: Handling Overload
Частые вопросы
Как перевести SLO 99,9% в бюджет ошибок?
Что считать ошибкой, если запрос успешен, но очень медленный?
Всегда ли первым растёт CPU?
Как понять, что ретраи усугубляют перегрузку?
Можно ли по нагрузочному тесту назвать точную вместимость продакшена?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.