Добро пожаловать
Добро пожаловать
Веб-масштабный флот содержит множество машин. В любой момент времени некоторые из них здоровы, некоторые запускаются, некоторые завершают работу, а некоторые тихо сломаны. Флот выживает благодаря тому, что каждая машина по запросу отвечает на два простых вопроса:
- /health — могу ли я сейчас обрабатывать реальные запросы?
- /version — какой код я выполняю?
Плюс метрический endpoint (обычно /metrics), который предоставляет счётчики и датчики (gauges) для сбора данных инструментами мониторинга.
В этом уроке вы узнаете, как проектировать эти endpoint'ы, чтобы они действительно отражали реальное состояние системы, что означают четыре «золотых сигнала» на уровне прокси и как наблюдаемые данные влияют на решения по масштабированию.
К концу урока вы сможете:
- Спроектировать endpoint /health, который обнаруживает реальные сбои в путях обработки, а не просто проверяет жизнеспособность процесса
- Спроектировать endpoint /version, позволяющий проверить, что деплой успешно выполнен
- Применить четыре «золотых сигнала» (задержка, трафик, ошибки, насыщенность) на уровне прокси
- Связать наблюдаемые метрики всплесков нагрузки с решениями по масштабированию: когда масштабировать вверх, когда сливать трафик (drain), когда вызывать дежурную смену
- Рассуждать о SLO и скорости сгорания бюджета ошибок как об операционной дисциплине, определяющей «насколько нам важно»
Два вида проверки состояния
Живость (Liveness) и готовность (Readiness)
Живость (Liveness): жив ли процесс вообще? Используется оркестраторами (Kubernetes, systemd) для принятия решения о перезапуске процесса.
Готовность (Readiness): готов ли процесс обрабатывать реальный трафик прямо сейчас? Используется балансировщиками нагрузки для принятия решения о пересылке запросов.
Это разные вопросы. Процесс, который жив, но не может подключиться к своей базе данных, является живым, но не готовым. Процесс, который запускается, является живым, но пока не готов.
Поверхностные и глубокие проверки состояния
Поверхностные: возвращают {"status": "ok"}, если HTTP-обработчик работает. Тривиально. Обнаруживают только остановку процесса.
Глубокие: фактически проверяют реальный путь запроса. Проверяют, что пул соединений с базой данных может вернуть соединение, кэш доступен, а зависимые сервисы отвечают. Обнаруживают функциональные сбои, которые пропускают поверхностные проверки.
Компромисс: глубокие проверки обходятся дороже (каждая из них по сути является синтетическим запросом) и могут вызвать каскадный сбой (если проверки здоровья каждого реплики нагружают базу данных, медленная база данных сделает все реплики нездоровыми, что выведет их из ротации, а это, в свою очередь, приведет к потере всей пропускной способности).
Лучшая практика: поверхностная проверка для проверки работоспособности (быстрая, дешевая, без внешних зависимостей) и более глубокая проверка для готовности к работе (с использованием кэшированных результатов и ограничением частоты запросов, чтобы не перегружать нижестоящие сервисы).
Конечные точки версии
/version возвращает коммит git, время сборки и имя сервиса. После развёртывания вы выполняете curl https://service.example.com/version и проверяете, что возвращенный коммит совпадает с тем, который вы отправили. Если он не совпадает, развёртывание молча завершилось с ошибкой.
Без /version устаревшее развёртывание может выглядеть как успешное и оставаться незамеченным в течение часов.
Минимальный формат ответа: {"service": "my-api", "git_commit": "abc1234", "build_time": "2026-05-19T10:00:00Z"}.
Задержка, Трафик, Ошибки, Нагрузка
Четыре числа покрывают большую часть операций
Из книги Google SRE. Четыре сигнала, которые вы измеряете на каждом уровне сервиса. Если вы правильно настроите мониторинг этих четырех показателей, вы обнаружите большинство проблем в продакшене раньше, чем пользователи.
Задержка: сколько времени занимает запрос? Отслеживайте распределения, а не только средние значения. p99 (99-й процентиль задержки) важнее среднего, потому что именно хвостовая задержка ощущается пользователями как «медленная работа». У сервиса со средней задержкой 50 мс и p99 в 5 000 мс есть реальная проблема, которую большинство пользователей не замечают, но 1% наиболее пострадавших — точно да.
Трафик: сколько запросов в секунду? Общее количество запросов, по эндпоинтам, по кодам состояния, по регионам. Базовые значения известны; настраивайте оповещения на аномалии (резкое падение = проблема с входящим трафиком; резкий всплеск = пиковая нагрузка или атака).
Ошибки: частота неудачных запросов. Различайте 4xx (ошибки клиента, не ваша вина) и 5xx (ошибки сервера, ваша вина). Отслеживайте частоту ошибок в процентах от трафика, а не в абсолютных значениях, чтобы оповещения работали при любой нагрузке.
Насыщенность: насколько заполнена система? Использование CPU, память, глубина пула соединений, длина очереди. Это опережающий индикатор. Насыщенность растет до того, как начнут деградировать задержка или ошибки. Тир с 90% насыщенностью находится в одном плохом минуте от коллапса очереди.
На уровне прокси-тира
Каждый сигнал проявляется на граничном уровне:
- Задержка на прокси: длительность рукопожатия TLS, время подключения к upstream, общее время запрос-ответ. Измеряются отдельно, так как относятся к разным частям пути.
- Трафик на прокси: общее количество запросов/сек, распределение по бэкендам (нагрев одного бэкенда сигнализирует о перекосе балансировщика нагрузки), разбивка по кодам состояния.
- Ошибки на прокси: 4xx от клиентов (ваши пользователи обращаются к недействительным конечным точкам), 5xx от бэкендов (сбой ваших сервисов), внутренние ошибки прокси (502 = бэкенд недоступен, 504 = превышение времени ожидания бэкенда).
- Насыщенность на прокси: количество сессий TLS, глубина пула соединений с вышестоящими серверами, загрузка CPU самого прокси (терминация TLS требует значительных вычислительных ресурсов).
Полезный совет: резкий рост количества ошибок 502 при низкой задержке бэкенда означает, что бэкенд обрывает соединение до отправки ответа (сброс соединения, сбой, нехватка памяти). Рост количества ошибок 504 означает, что бэкенд работает медленно, но все еще отвечает. Читайте код ошибки; он указывает, где именно происходит сбой.
Чтение сигналов
Ваша панель отображает следующие данные за последние 10 минут:
- Трафик: примерно стабильный на уровне 800 запросов/с (без всплеска)
- Задержка: p50 стабильна на уровне 40 мс, p99 выросла с 200 мс до 2 500 мс за 5 минут и продолжает расти
- Ошибки: уровень 4xx стабилен на отметке 0,3% (нормальный фоновый уровень); уровень 5xx вырос с 0,1% до 1,2% (в основном 504 Gateway Timeout)
- Насыщенность: загрузка CPU бэкенда выросла с 45% до 78% за те же 5 минут; загрузка CPU прокси стабильна на уровне 30%
Когда масштабировать, когда сливать, когда будить
Решения по ёмкости требуют триггеров
Наблюдать за метриками легко. Дисциплина заключается в том, чтобы знать, когда на них реагировать.
Масштабируйте вверх, когда: насыщение превышает устойчивый порог (например, CPU бэкенда >70% в течение 5 минут), или глубина очереди превышает целевое значение, или p99 задержки превышает SLO. Триггер должен срабатывать до того, как система сломается, а не в момент поломки.
Сливайте реплику, когда: она стабильно работает медленно / с ошибками, в то время как другие реплики в порядке (одна перегретая реплика часто указывает на проблему на уровне хоста, а не приложения), или при развёртывании новой версии, или при корректном выводе реплики из эксплуатации.
Будите человека, когда: SLO нарушается быстрее, чем позволяет бюджет ошибок, или триггер насыщения срабатывает, но автомасштабирование не справляется с нагрузкой, или появляется каскадный паттерн (одновременно растут уровень ошибок и уровень повторных попыток).
Не будите, когда: единичная плохая минута разрешается сама по себе, или фоновые пакетные задачи вызывают ожидаемые периодические всплески, или шум превышает порог (неверен порог, а не система).
Цели уровня обслуживания (SLO) и расход бюджета ошибок
Цель уровня обслуживания (SLO) определяет допустимый уровень производительности: «процент успешных запросов >= 99,9% за 28-дневное окно». Дополнение (0,1%) представляет собой бюджет ошибок.
Скорость расхода (burn rate): скорость, с которой вы расходуете бюджет ошибок. Если вы расходуете 10% бюджета за 1 час, скорость расхода в 240 раз выше допустимой (1 час составляет 1/672 от 28-дневного окна; расход 10% за это окно = 10% × 672 = 6720% прогнозируемого расхода за полное окно, тогда как допускается только 100%).
Алерты на основе скорости расхода в нескольких окнах: сигнал тревоги срабатывает, когда и короткое окно (5 минут при скорости 14,4x), и длинное окно (1 час при скорости 6x) расходуют бюджет быстрее допустимого. Это позволяет обнаруживать как быстрые сбои, так и медленное деградирование.
Почему это важно для мощности: сервис, работающий с SLO 99,9% и запасом в 1%, может поглощать небольшие перебои. Сервис с показателем 99,93% (едва-едва соответствующий SLO) находится в шаге от нарушения из-за одного плохого дня. Решения по мощности должны быть направлены на обеспечение комфортного запаса по SLO, а не на минимально допустимый уровень.
Решение по мощности под наблюдением
Для вашего сервиса установлена цель уровня обслуживания (SLO) в 99,9% успешных запросов за 28 дней. Текущее состояние по данным мониторинга за последний час:
- Процент успешных запросов: 99,5% (устойчиво в течение 30 минут)
- CPU бэкенда: в среднем 82% по всему флоту (целевое значение 70%)
- Задержка p99: 800 мс (целевое значение SLO: <500 мс)
- Трафик: 1 400 запросов/с, рост с базовых 1 000 запросов/с (на 40% выше нормы; тенденция к росту сохраняется)
- Автомасштабирование: настроено на добавление реплик при CPU > 80% в течение 5 минут; в данный момент идёт масштабирование, в ходе которого за ~90 секунд будет добавлено 3 реплики
Спроектируйте план наблюдаемости запуска
Синтез
Теперь вы можете спроектировать /health, который выявляет реальные сбои, /version, позволяющий верифицировать деплои, дашборды с четырьмя «золотыми сигналами» на уровне прокси-шлюба, а также триггеры по пропускной способности, привязанные к скорости сгорания SLO.
Примените все четыре компонента.
Ваша команда запускает search.example.com (сервис поиска из урока о режимах отказов). Команда хочет внедрить наблюдаемость, которая выявляет проблемы до того, как их заметят пользователи, с четкой матрицей решений «страница или нет». SLO: 99,9 % успешных запросов, p99 задержка < 300 мс, за 28-дневное окно.
Завершение курса
Завершение курса
Вы завершили все пять уроков:
- Прокси и источники: форма на уровне edge, которую используют практически все публичные веб-сервисы
- Бесстатусное горизонтальное масштабирование: почему бесстатусный слой масштабируется дёшево и как определить его размер
- Разделение входящего и исходящего трафика: почему один узел превращается в два, и какой сценарий сбоя это обуславливает
- Режимы сбоя и радиус поражения: SPOF (одинаковые точки отказа), каскадные сбои, постмортемы, безвинные пункты плана действий
- Наблюдаемость и ёмкость (эта тема): что измерять, чтобы проблемы проявлялись до того, как их заметят пользователи
Сквозная тема: распределённая система веб-масштаба — это не магия. Это небольшой набор паттернов (обратный прокси, бесстатусные реплики, разделение входящего/исходящего трафика, bulkheads и circuit breakers, четыре золотых сигнала), продуманно скомпонованных. Как только вы распознаёте эти паттерны, вы видите их в каждой production-архитектуре.
Сопутствующие уроки: пять уроков в формате «геометрия-*» переосмысляют тот же материал с точки зрения теории графов и геометрии. Их можно проходить в любом порядке.
Отличная работа.