The Jerusalem PostIsraeli extremist settlers use sheep farms, intimidation to expand West Bank control, CBS reportsESPNBills, Josh Allen outlast Rams in overtime on MNFESPN DeportesAllen, el héroe en un espectacular juego en Sofi StadiumBollywood HungamaSidharth Malhotra suffers leg injury, shares photo with a witty note!Daily MaverickSECOND CHANCE: Former Springbok coach Jake White will lead ‘best-prepared’ Fiji to RWC 2027RTP Desporto12h30 Ambiente difícil em Lens, Porto complicado diz PellegriniRTL BoulevardMan (27) stichtte bewust brand tijdens Pride en verheerlijkte ISAntara NewsIndonesia seeks land certainty to accelerate 3 million homes programVariety‘Death in Paradise’ Gets Its First International Adaptation in Croatia, Promises ‘Murder Mystery, Humor, Warmth and a Strong Sense of Place’ (EXCLUSIVE)ZDF heuteEntdecken Sie das ZDF-Nachrichtenstudio
The Daily Newsstand · Free, Always
Tuesday, October 13, 2026

Бюджет 999: как в Авито считают надёжность и почему не копируют модель Google

Translate

Привет, Хабр! Меня зовут Иван Тарасов, я TUL Architecture Governance в техплатформе Авито. Одна из моих команд — SLA — создаёт условия для повышения технической надёжности, а также развивает инструменты NFR и сценарии стабильности.

В этой статье я расскажу, как в Авито устроена система измерения надёжности: от SLI/SLO/SLA и разницы между Stability Rate и Uptime, до устройства NFR для REST/RPC-сервисов, шин данных и кастомных операций.

Также поясню, чем концепция бюджета ошибок в Авито отличается от канонического описания в книге Google SRE, и почему это не случайное отклонение, а намеренное решение.

Содержание:

Вступление

Когда речь идёт о надёжности сервисов, в бигтех часто идут по одному сценарию: открыть книгу Google SRE, процитировать главу про error budget и нарисовать формулу availability. Но дело в том, что эта книга писалась конкретной компанией с конкретной операционной моделью, а не как универсальный постулат для всех, у кого есть продакшн. У Авито тысячи сервисов, десятки продуктовых команд с разной степенью зрелости, скользящий, а не фиксированный отчётный период, и отсутствие юридически оформленных SLA с пользователями. В такой конфигурации механически перенести практики Google не получится 

SRE Book написан под технический продукт, когда им является инфраструктура, например Cloud. А Авито предоставляет услуги напрямую людям.

Терминология и почему SLI, SLO, SLA не синонимы

Прежде, чем говорить о бюджетах ошибок, стоит разъяснить три аббревиатуры, которые в разговорной речи инженеры смешивают в кашу.

Это спидометр в автомобиле, который показывает текущую скорость

Это спидометр в автомобиле, который показывает текущую скорость

1. SLI (Service Level Indicator) — это фактическое состояние метрик. Не то, что должно быть, а то, что есть прямо сейчас: реальная доля успешных запросов, реальное время ответа.

Это запрещающий знак на дороге, который не позволяет ехать со скоростью выше указанной

Это запрещающий знак на дороге, который не позволяет ехать со скоростью выше указанной

2. SLO (Service Level Objectives) — целевое состояние тех же метрик, то есть ограничение допустимого порога. SLO для времени ответа или доли ошибок работает как ограничение скорости, где фактическое значение должно быть меньше порога. А для уровня надёжности логика обратная: фактическое значение должно быть выше порога.

Это кодекс об административных правонарушениях, который регламентирует штрафы за превышение скорости

Это кодекс об административных правонарушениях, который регламентирует штрафы за превышение скорости

3. SLA (Service Level Agreements) — это то, что происходит, когда SLI перестаёт удовлетворять SLO. По сути SLA описывает последствия, а не саму метрику.

Различия и разграничения невелики, но именно это определяет всю дальнейшую архитектуру системы. SLI — это сырые данные, SLO — договорённость о допустимых границах, SLA — реакция на нарушение договорённости. Когда эти три уровня перепутаны (на практике перепутаны они бывают часто), обсуждение надёжности превращается в спор о терминах вместо спора о цифрах.

Разобравшись с терминами и отличиями, надо понять, какие именно индикаторы нужно измерять и как их считать.

Stability Rate против Uptime: ловушка усреднения

Один из ключевых вопросов при построении системы измерения надёжности в том, как агрегировать метрику по времени. Казалось бы, есть периоды наблюдения, в каждом подсчитана доля ошибок, нужно свернуть это в одно число. На практике здесь скрыта ловушка, которая наглядно демонстрируется на паре формул.

Stability Rate — это показатель стабильности по метрикам, измеряющим надёжность и качество выпускаемых релизов. Он считается так:

Stability Rate = 1 – (errors / total)

Это доля успешных операций от общего числа, усреднённая метрика, которая размазывает провалы по всему объёму трафика.

Uptime — это показатель времени непрерывной и стабильной работы сервиса без сбоев и перезагрузок. Он считается принципиально иначе:

Uptime = 1, если Stability Rate ≥ SLO, иначе 0

Это уже не усреднение, а бинарный флаг: либо период (минута, час или день) считается стабильным целиком или не считается вовсе, без компромиссов.

Разница между этими двумя подходами ощутимая и измеримая. Покажу на простом примере. Возьмём пять периодов наблюдения с Stability Rate равным 0.999, 0.99, 0.98, 0.95 и 0.99. Усреднённый Stability Rate по этим пяти периодам составит:

(0.999 + 0.99 + 0.98 + 0.95 + 0.99) / 5 = 0.982

Число выглядит вполне пристойно: 98.2%, почти «три девятки». Теперь посчитаем Uptime для тех же пяти периодов при условии, что SLO зафиксировано на уровне 0.99. Периоды со Stability Rate ниже порога (0.98 и 0.95) получают Uptime = 0, остальные Uptime = 1:

Uptime = (1 + 1 + 0 + 0 + 1) / 5 = 0.6

60% против 98.2% — это не погрешность округления, а два совершенно разных представления. 

Усреднённая метрика прощает провалы, если рядом с ними были достаточно зелёные периоды. Система как бы говорит, что в среднем всё неплохо. Бинарная метрика провалы не прощает, она честно фиксирует, что половину времени наблюдения сервис не соответствовал целевому уровню, и никакие соседние успешные периоды это не компенсируют.

Оба числа технически правдивы, но отвечают на разные вопросы. Stability Rate сообщает, какая в среднем доля запросов была успешной, а Uptime, как часто сервис вообще держал обещанный уровень качества. Нас в нашей работе интересует именно Stability Rate. Он даёт более детальную информацию, чтобы оценить объём проблем.  

Тут еще больше контента

Тут еще больше контента

Канонический Error Budget по Google SRE

Перед разбором модели Авито посмотрим, как концепция бюджета ошибок описана в книге Google SRE (Site Reliability Engineering). Это практическое руководство от Google, где представлены создание и управление системой обеспечения надёжности в бигтехе.

Бюджет ошибок (Error Budget) — это суммарный объём ошибок, который определяет, как часто сервис может проявлять ненадёжность в пределах заданного отрезка времени. Это не абстрактная метрика, а конкретный лимит, какой процент медленных запросов или «пятисоток» сервис имеет право допустить.

Бюджет ошибок нужен для баланса между внедрением фичей и надёжностью. Пока этот бюджет не исчерпан, команда может катить эксперименты, ускорять релизы, пробовать оптимизации. Как только бюджет закончился, приоритет автоматически смещается в сторону стабилизации.

Что расходует бюджет? Может, снижение SLI из-за отключения сети или сбоя в дата-центре тоже расходует бюджет ошибок? Ответ в книге Google SRE — да, расходует. Бюджет ошибок в классической модели не делает различий между нашей виной и внешними обстоятельствами. Инфраструктурный сбой съедает тот же лимит, что и баг в релизе. Это принципиальный момент, потому что он превращает error budget из инструмента контроля качества кода в инструмент контроля совокупной надёжности пользовательского опыта. Сервису пользователя всё равно, по чьей вине он не получил ответ вовремя.

После превышения бюджета релизы останавливаются, и наступает Release freeze. Команда физически не может выкатывать новый код в продакшн, пока бюджет не восстановится.

SLO определяет менеджер продукта. Это не техническое решение и не решение SRE-команды: целевой уровень надёжности выставляется тем, кто отвечает за продуктовую ценность и понимает, какой уровень деградации пользователи готовы терпеть, а какой — нет.

В итоге получается строгий, но гибкий инструмент поиска баланса между надёжностью и новыми фичами. Строгий, потому что при исчерпании бюджета релизы действительно останавливаются, без переговоров. Гибкий, потому что до тех пор, пока бюджет не исчерпан, команда полностью свободна в выборе того, на что его тратить.

Эта модель считается индустриальным стандартом. Авито отошёл от неё в нескольких ключевых точках.

Почему в Авито не как в Google

Между двумя моделями есть архитектурные отличия, в которых Авито выбрал не общепринятый путь. 

  1. Скользящее окно вместо фиксированного периода

SRE устанавливает бюджет ошибок на фиксированный промежуток времени, например, на квартал. В этом есть предсказуемый ритм: в начале квартала бюджет полный, к концу он или исчерпан, или нет. В момент границы периода счётчик обнуляется целиком, независимо от того, что происходило накануне.

В Авито SLI считается на скользящем окне в 14 дней. Это принципиально иная динамика. Нет резкого обнуления в фиксированную дату, но есть выпадение старых инцидентов из окна расчёта и включение новых.

Инцидент недельной давности продолжает давить на метрику, а инцидент, которому две недели, автоматически перестаёт учитываться без ручного вмешательства и без ожидания начала нового отчётного периода.

Это выбор в пользу более плавной и более забывчивой системы. Реагирует быстрее, но и прощает быстрее.

  1. Мягкий режим на превышении бюджета

Второе отличие касается не механики расчёта, а текущей стадии внедрения контрольных мер. По SRE исчерпание бюджета жёстко останавливает релизы. В Авито на данный момент при выходе за рамки бюджета нет платформенных ограничений к релизам, команда не блокируется технически.

Переход к жёсткому release freeze рискует получить обратный эффект. Команды начнут саботировать систему, а не встраивать в процесс принятия решений.

  1. Критичность вместо прямого SLO

Третье и основное расхождение в том, как мы определяем целевой уровень надёжности. В SRE это делает продакт менеджер. В Авито между продактом и конкретным числовым порогом стоит промежуточный слой критичности сценария.

SLO в Авито определяется критичностью. Продакт и разработчики меняют критичность сценария, а не сам SLO напрямую. Это важное разделение ответственности. Вместо того, чтобы просить продуктового менеджера каждый раз вручную выставлять числовое значение вроде 99.95%, ему предлагается более понятная и менее подверженная ошибкам категория: насколько критичен тот или иной пользовательский сценарий. А уже из категории критичности система выводит конкретные пороги.

Трешхолды NFR определяют разработчики. Критичность сценария задаёт продуктовую и бизнес-логику допустимого уровня деградации, но конкретные технические пороги определяет инженерная команда, которая лучше понимает характеристики своих систем.

Так получается трёхуровневая модель распределения ответственности, вместо двухуровневой модели SRE:

1. Продукт и разработка решают, насколько критичен сценарий (это управленческое, а не техническое решение).

2. Критичность через систему правил трансформируется в SLO (он выставляется сервисам и операциям, которые они реализуют для обеспечения работы сценариев для пользователей).

3. Разработчики определяют конкретные технические пороги NFR, при которых сценарий считается работающим корректно.

И есть ещё одно важное отличие. В Авито отсутствуют SLA с пользователями. В SRE-модели SLA — это то, что происходит при нарушении SLO с юридическими или финансовыми последствиями. В Авито этого нет вообще. Наша система — это внутренний инструмент, он не для выполнения контрактных обязательств перед пользователями. Но есть краевые случаи с определёнными категориями клиентов Авито, когда такой договор присутствует, но так как это корнеркейсы, то команды, обеспечивающие надёжность для таких пользователей, самостоятельно делают надстройку для мониторинга и платформа не заточена под эти кейсы.

Жми сюда!

Жми сюда!

Откуда берётся SLO: критичность сценариев

В Авито именно критичность сценариев определяет общий уровень надёжности. Она показывает серьёзность последствий деградации. Критичность разбита по уровням.

Mission Critical — это уровень критичности сценария, при котором происходит полная остановка ключевых функций, массовый отток пользователей, серьёзные репутационный и финансовый ущербы. Работа большинства бизнес-направлений невозможна. Нет альтернативных сценариев.

При его наступлении инцидент-менеджеры запускают disaster-инцидент — режим, в котором проблему пытаются устранить максимально быстро, не обращая внимания на любые сопутствующие неудобства.

Business Critical — это уровень критичности сценария, когда работа большинства бизнес-направлений затруднена или останавливается работа одной из ключевых функций. Сюда относятся три типа сценариев:

  • Которые ведут пользователя к транзакции

  • Которые обеспечивают посттранзакцию

  • Time sensitive – сценарии, которые сложно выполнить отложено.

Business Operational — это уровень, когда происходит ухудшение пользовательского опыта, например, не открываются отзывы. Работа бизнес-направлений продолжается, но с трудностями.

Такое разделение — это не техническое ограничение, а осознанное решение. Уровни критичности сценариев определяют уровни важности сценариев для пользователей и Авито, а так же помогают не фреймиться на технические термины.

NFR: пороги, которые считает не SRE, а сами разработчики

Система SLI/SLO/SLA и модель критичности задают верхнюю рамку. Но чтобы система реально работала, нужны строгие правила, которые зададут абстрактным уровням конкретные рамки в реальном времени. Этот слой называется NFR (non-functional requirements). Нефункциональные требования превращают бюджет ошибок из концепции в инструмент в коде сервисов.

Для синхронных вызовов (REST и RPC) используется формула:

SLI = 1 - (exceed.latency + errors) / total

Exceed latency — слагаемое, равноправное с errors. Это значит, что запрос, который вернул технически корректный ответ, но сделал это слишком медленно, превысив установленный порог latency, учитывается наравне с запросом, который вернул явную ошибку. Для конечного пользователя разница между ошибкой и промедлением часто несущественна. В обоих случаях сценарий не был выполнен в приемлемом виде. Формула это отражает буквально, вместо того чтобы отслеживать latency и error rate как две разрозненные метрики, которые потом нужно сводить вручную. 

Для асинхронного взаимодействия NFR устроена принципиально иначе, поскольку нет прямого запроса-ответа, но есть поток сообщений. Они обрабатываются двумя сигналами ack и nack. Первый означает успешную обработку события, а nack — неуспешную: тогда сообщение не пропускается, а обрабатывается повторно. 

На снижение SLI для консьюмеров шин данных влияют:

Nack — учитывается как correctness, то есть нарушение корректности приводит к остановке обработки очереди до момента успешной обработки;

Processing time — время обработки сообщения;

freshness — свежесть данных, время между попаданием события в очередь и его успешной обработкой.

Это не просто успех/неуспех, а три измерения качества: можно обработать сообщение технически правильно, но слишком поздно, можно застрять на невозможности обработать сообщение, а можно уложиться в оба порога по времени, но сам факт обработки занял непозволительно много времени относительно ожидаемого SLA на freshness.

Как устроен подсчёт метрик внутри одного вызова обработчика батча сообщений:

Логика состоит из семи шагов:

  1. Каждая попытка обработать сообщение из шины данных хендлером приводит к созданию события, которое может произойти успешно или неуспешно.

  2. Инициализируется счётчик (два независимых счётчика: обработанные, пропущенные).

  3. Неинтересующие события можно просто скипнуть, Skip не влияет на метрику NFR.

  4. При этом есть отдельная ветка: при ошибке будет nack, и весь батч помечается как нарушивший correctness, а все остальные счётчики в этом случае не учитываются.

  5. Когда сообщение помечается как success, система просто убеждается, что ни одно сообщение не было забыто.

  6. Freshness замеряется по первому сообщению в батче, если обработка батчевая, то есть свежесть считается по самому старому элементу партии, а не по каждому сообщению индивидуально и не по последнему.

На уровне кода это выглядит так:

// Handler возвращает BatchResult
func handleBatch(events []*MyEvent) databus.BatchResult {
	processed := 0
	skipped := 0

	for _, event := range events {
		if event == nil {
			skipped++
			continue
		}

		if err := processEvent(event); err != nil {
			return databus.Nack()
		}

		processed++
	}

	return databus.Acks(processed,
		databus.WithSkips(skipped))
}

Эта же логика есть не только в Go, но и в Python. Поэтому NFR решение не для одного стека, а мультиязычный инструмент.

Кастомные NFR, когда API и консьюмеры не покрывают всей картины

Что ещё контролировать, кроме API и консьюмеров? Практически всё остальное. Есть операции, которые влияют на пользователей, но не укладываются в формат REST/RPC-вызова и в обработку сообщения из шины данных.

Для этого есть кастомные NFR, которые могут измерять успешность и время выполнения произвольных операций:

– срабатывания крона;

– итерации воркера.

Все важные процессы, которые выполняют операции, влияющие на пользователей, должны быть покрыты метриками NFR, вне зависимости от того, укладываются они в готовый шаблон или нет.

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

  • Указываем время старта — отсчёт времени выполнения операции

  • Если что-то пошло не так, то завершаем операцию и пишем ошибку

  • Если всё успешно, завершаем операцию с указанием времени выполнения

Заключение: применимость модели и куда это движется

В Авито получилась не подобие, а переосмысление классической SRE-модели, причём с модификацией во всех четырёх ключевых точках, где обычно есть основная сложность внедрения error budget на практике.

От SRE унаследована сама идея бюджета ошибок как инструмента поиска баланса между надёжностью и скоростью разработки, использование SLI/SLO как базового языка описания надёжности, и принцип, что даже внешние по отношению к сервису сбои расходуют общий бюджет, а не списываются как чужая.

Что в Авито переосмыслено:

Время. фиксированный отчётный период заменён на скользящее окно в 14 дней. Это более отзывчивая, но и более забывчивая модель.

Жёсткий release freeze при исчерпании бюджета пока не включён. Вместо этого действует более мягкий режим.

SLO определяются критичностью. Продакт и разрабы меняют критичность, а не SLO.

Трешхолды NFR в руках разработчиков, которые реально понимает технические характеристики своей системы.

Отсутствует SLA с пользователями. Вся конструкция работает как внутренний управленческий инструмент.

Бюджет ошибок — это не готовая формула, которую можно вставить в мониторинг и забыть, а организационный механизм, каждый параметр которого нужно осознанно подстроить под себя. Слепое копирование фиксированного квартального окна или немедленное включение жёсткого release freeze из SRE book обречено.

Продолжением развития бюджета ошибок в Авито будет постепенное ужесточение последствий при исчерпании бюджета без ограничений на релизы, а также расширение охвата NFR на всё больше типов операций, например успешность отрисовки экранов и микрофронтов. Это необходимо, потому что в реальной микросервисной архитектуре большой платформы граница между API и его потребителями почти никогда не бывает полностью закрытой, на пользователя влияет много всего другого.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.