∿Метрики и
наблюдаемость
Главы темы 1
1.2

Мониторинг: регулярные измерения и история

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

Главное в главе

Число на панели можно понять, только если известны объект, единица измерения и окно времени, за которое оно посчитано.

Раздел
Основы наблюдаемости
Уровень
Начальный · Python знаком
Связанные главы
1.1 — сервис products-api, 1.4 — метрики
Зачем это знать
Отличать изменение в работе сервиса от случайного числа на экране

§1Что такое мониторинг

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

Сравнение из жизни
Давление: один раз и каждое утро

Человек измерил давление один раз и получил число. Если он измеряет давление каждое утро и записывает в тетрадь, врач по записям определяет, с какого дня оно начало расти.

Проверка сайта и мониторинг

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

Мониторинг — регулярный сбор, хранение и анализ данных о работе системы. Он нужен, чтобы замечать изменения в поведении сервиса и реагировать на них раньше, чем придёт жалоба пользователя.

Разработчик, который раз в день открывает сайт и смотрит, загрузилась ли страница, делает ручную проверку. Мониторингом это становится, когда измерения выполняются по расписанию, без участия человека, а результаты складываются в историю, к которой можно вернуться.

Мониторинг состоит из пяти шагов, и они выполняются по порядку.

  1. Измерить

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

  2. Сохранить

    Значение записывается вместе с моментом измерения. Без отметки времени число не поставить в историю.

  3. Сопоставить

    Значения группируют и сравнивают: по маршрутам, по экземплярам, с тем же часом вчера.

  4. Показать

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

  5. Отреагировать

    Правило проверяет условие, например «доля ошибок выше 2% в течение пяти минут», и отправляет уведомление человеку.

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

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

Первоисточник: Google SRE Book · Monitoring Distributed Systems ↗

Первый шаг мониторинга — измерить. Следующий раздел разбирает, из чего состоит результат измерения.

§2Из чего состоит показатель

На панели стоит строка «CPU 80%». Для решения её недостаточно: непонятно, чей это процессор, как посчитан процент и за какой промежуток времени. У любого показателя в мониторинге четыре части.

Первая часть — объект: чей это показатель. Объектом бывает процесс, сервер, маршрут или очередь, например процесс API на сервере api-2. Вторая — величина: что измеряется, например длительность обработки запроса к /products. Третья — единица, в которой выражено значение, например миллисекунды. Четвёртая — способ расчёта: как из отдельных измерений получено одно число, например среднее за последнюю минуту.

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

Способ расчёта хорошо виден на том же CPU. В Linux утилита top по умолчанию показывает загрузку процесса относительно одного ядра, поэтому процесс, полностью занявший четыре ядра, получит 400%. Другая программа делит ту же нагрузку на число ядер и показывает 100%. Обе цифры верны, но посчитаны разными способами, и без подписи сравнивать их нельзя.

Пример

Одно название, два разных числа

На панели «Длительность запросов» показано 85 мс, а на соседней панели с тем же названием — 380 мс. Разницу объясняют подписи. Первая панель показывает медиану — значение, которое делит запросы пополам: половина быстрее, половина медленнее. Вторая показывает среднее арифметическое за ту же минуту.

Медиана

85 мс

Два медленных запроса из двадцати почти не влияют на медиану.

Среднее

380 мс

Те же два запроса по 3 секунды поднимают среднее в четыре с лишним раза.

Цифры взяты из прогона главы 1.4: почти все запросы занимают около 85 мс, а два длятся около трёх секунд. Обе панели показывают правду, но название без способа расчёта сбивает с толку.

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

§3Временной ряд: значение и момент измерения

Одно измерение отвечает только на вопрос «сколько сейчас». Для мониторинга важнее, как значение менялось и когда начались изменения. Для этого измерения одной величины собирают в последовательность.

Временной ряд — последовательность значений одной величины у одного объекта, упорядоченная по времени. Каждая точка ряда — пара «момент измерения и значение».

Ниже два ряда загрузки CPU. Последнее значение у них одинаковое — 80%. Переключите ряды и сравните форму линии.

CPU · два временных ряда
100%50%0%09:0009:05

78 → 80 → 82 → 79 → 81 → 80%. Последнее значение: 80%.

Значения придуманы для сравнения формы графика; это не измерения CPU стенда.
Рис. 1.2.1 одно последнее значение, две разные истории

Кнопки меняют ряд. Точки — шесть измерений с 09:00 до 09:05, наведите на точку, чтобы увидеть значение. Значения придуманы для сравнения, это не измерения стенда.

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

Ряд имеет смысл, только если все его точки относятся к одному объекту и посчитаны одинаково. Допустим, сервер заменили новым, а измерения продолжили писать под старым именем. Линия на графике останется непрерывной, но слева от замены будет один сервер, а справа другой. Поэтому в системах мониторинга объект указывают в описании самого ряда: названия панели для этого недостаточно.

Первоисточник: Prometheus · Data model ↗

Точки ряда стоят на расстоянии друг от друга. Следующий раздел показывает, что зависит от этого расстояния.

§4Частота измерений и что происходит между ними

Измерения делают через равные промежутки: раз в пять секунд, раз в минуту. Этот промежуток называют интервалом измерения, и от него зависит, какие события попадут в историю.

Пример

Всплеск между двумя измерениями

Загрузку CPU проверяют раз в минуту. В 12:00:10 процесс на двадцать секунд полностью занял процессор, а к 12:01:00 нагрузка спала. Значения в 12:00 и в 12:01 низкие, и всплеска на графике нет. При проверке раз в пять секунд всплеск дал бы четыре точки подряд.

ИнтервалЧто видноОграничение
5 секундКороткие всплески, быстрые измененияВ 12 раз больше точек, чем при минутном интервале: больше места и нагрузки на хранилище
1 минутаУстойчивые измененияВсплески короче минуты могут пропасть между измерениями
1 часСуточные и недельные закономерностиДля разбора конкретного сбоя почти бесполезен

Часть потерь снимает выбор типа показателя. Счётчик, который только растёт, не пропустит события между измерениями: если за минуту пришло 600 запросов, счётчик вырастет на 600, когда бы его ни прочитали. Мгновенное значение, например текущая длина очереди, такой гарантии не даёт. Разница между ними разобрана в главе 1.4.

На стенде Prometheus опрашивает API раз в пять секунд, чтобы после пары запросов изменения сразу появлялись на графике. В рабочих системах интервал выбирают по двум вопросам: насколько короткие изменения нужно замечать и сколько данных готовы хранить.

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

§5Окно времени меняет смысл числа

Фраза «пять ошибок» ничего не говорит о состоянии сервиса. Пять ошибок за секунду при десяти запросах означают, что сбой получает половина пользователей. Пять ошибок за сутки при миллионе запросов — редкий случай, который, возможно, не требует срочной реакции.

Поэтому количество почти всегда пересчитывают в долю.

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

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

Python · доля ошибок за одно окно
failed_requests = 5      # неуспешные запросы за 5 минут
all_requests = 1000      # все запросы за те же 5 минут

error_ratio = failed_requests / all_requests
print(f"{error_ratio:.1%}")
Вывод в терминале
0.5%

error_ratio получает значение 0,005. Формат :.1% умножает число на 100 и выводит один знак после запятой.

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

§6Сложение количеств вместо усреднения процентов

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

Пример

Две реплики API

Первая реплика за пять минут обработала 10 запросов, из них 5 с ошибкой, — это 50%. Вторая за те же пять минут обработала 990 запросов без ошибок — 0%.

Неверно

Среднее процентов

(50% + 0%) / 2 = 25%

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

Верно

Сумма количеств

(5 + 0) / (10 + 990) = 0,5%

Сначала складываем ошибки, затем все запросы, и только потом делим.

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

У этого примера есть и вторая сторона. Общая доля 0,5% выглядит спокойно, а на первой реплике сбоит каждый второй запрос. Общий показатель скрывает проблему одного экземпляра, поэтому на панели держат и общую долю, и разбивку по экземплярам.

Доля посчитана верно. Остаётся понять, много это или мало.

§7С чем сравнивать: базовый уровень

В 14:00 каталог обработал 300 запросов в минуту. Много это или мало, по одному числу не понять. Нужен базовый уровень — значение, которое считается обычным для этого времени и этого сервиса.

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

СравнениеЧто показываетКогда сбивает с толку
С предыдущей минутойРезкий скачок или провалОбычный утренний рост трафика выглядит как аномалия
С тем же часом вчераОтклонение от суточного ритмаВчера был праздник или распродажа
С тем же днём неделю назадОтклонение с учётом дня неделиЗа неделю вышла новая версия, и обычное поведение изменилось

Базовый уровень нужен и для правил уведомлений. Порог «больше 500 запросов в минуту» в рабочий день будет срабатывать постоянно, а ночью пропустит настоящий всплеск. Чем точнее известно обычное поведение сервиса, тем точнее можно описать необычное.

Известно, как читать и сравнивать показатель. Следующий раздел отвечает на вопрос, какие показатели нужны сервису.

§8Что измерять у сервиса

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

Latency

Задержка

Сколько времени занимает обработка запроса. Пример: длительность ответа /products, отдельно для успешных и ошибочных.

Traffic

Трафик

Какой объём работы поступает. Пример: запросы в секунду.

Errors

Ошибки

Какая доля запросов завершается неуспешно. Пример: доля ответов HTTP 500.

Saturation

Насыщение

Насколько заняты ограниченные ресурсы. Пример: занятые соединения с базой, длина очереди заданий.

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

Кроме самого API, у сервиса есть окружение. Очередь может расти при свободном процессоре, если обработчики ждут ответа внешней системы, поэтому одного сервера для мониторинга мало.

ОбластьПоказателиКакую проблему выявляет
ПриложениеЗапросы, ошибки, длительности, активные запросыУхудшилось обслуживание пользователей
Фоновые заданияВремя ожидания в очереди, время выполнения, повторы, отказыAPI ответил «принято», а документ не готов через десять минут
ЗависимостиЗанятые соединения, время ожидания соединения, длительность обращенияПриложение ждёт базу данных или внешний API
ИнфраструктураCPU, память, диск, сетьНе хватает ресурсов или неисправна среда
Пример

Отчёт, который никогда не придёт

Маршрут POST /reports ставит задачу построения отчёта в очередь и сразу отвечает кодом 202 Accepted. С точки зрения HTTP всё прошло успешно и быстро. Если обработчики очереди остановились, пользователь отчёт не получит, а показатели API останутся идеальными. Проблему покажут только показатели очереди.

Первоисточник: Google SRE Book · The Four Golden Signals ↗

Все эти показатели сервис сообщает о себе изнутри. Есть и второй источник данных: проверка сервиса снаружи.

§9Проверка снаружи и показатели изнутри

Сервис можно измерять из двух положений: снаружи, так же, как с ним работает пользователь, и изнутри, по данным самого приложения.

Сравнение из жизни
Тайный покупатель и кассовая книга

Работу магазина проверяют двумя способами. Тайный покупатель заходит с улицы и пробует купить товар. Бухгалтер смотрит кассовую книгу и складские записи.

Проверка снаружи и показатели изнутри

Внешняя программа отправляет сервису запрос, как пользователь, и проверяет ответ. Сам сервис сообщает свои внутренние показатели: длину очереди, занятые соединения, время этапов.

Мониторинг чёрного ящика (black-box monitoring) — проверка поведения системы через её внешний интерфейс, без знания внутреннего устройства. Внешний агент отправляет запрос и проверяет ответ: пришёл ли он, какой у него код, сколько он занял.

Мониторинг белого ящика (white-box monitoring) — измерение показателей, которые система сообщает о себе изнутри: длина очереди, число занятых соединений, время отдельных этапов обработчика.

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

Проверка снаружи охватывает весь путь АгентGET /products → DNSимя → адрес → Сеть и TLSсертификат → Балансировщиквыбор экземпляра → Приложениеобработчик Показатели изнутри видны только здесь длина очереди · занятые соединениядлительность этапов обработчика Здесь внутренние показатели не измеряют ничего:истёкший сертификат заметен только снаружи
Рис. 1.2.2 что охватывает каждая из двух проверок

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

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

Измерения из обоих источников собраны. Последний шаг мониторинга превращает их в действие.

§10От измерения к действию: правило и уведомление

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

Правило составляют по проблеме пользователя. Состояние отдельного ресурса для этого подходит хуже. «Доля ошибок /products выше 2% в течение пяти минут» означает, что пользователи получают сбои. «CPU выше 90%» говорит только о загрузке процессора, которая для вычислительной задачи может быть обычной.

В правиле из примера четыре части. Показатель — доля ответов HTTP 500 на /products. Порог — больше 2%. Длительность — условие выполняется 5 минут подряд. Получатель — дежурный инженер сервиса каталога.

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

§11Частые ошибки

Что делаютЧто получаетсяКак правильно
Смотрят только на последнее значениеУстойчивая нагрузка и резкий рост выглядят одинаковоСмотреть историю ряда и сравнивать с базовым уровнем
Считают среднее от процентов разных репликРеплика с десятью запросами весит столько же, сколько реплика с тысячейСкладывать количества и делить сумму на сумму
Берут числитель и знаменатель из разных оконДоля ошибок получается в разы меньше или больше настоящейСчитать оба количества за одно окно и по одним маршрутам
Показывают отсутствие запросов как 0% ошибокОстановленный сервис выглядит исправнымВыводить «нет данных», когда знаменатель равен нулю
Проверяют доступность только через /healthСбой рабочего маршрута остаётся незамеченнымПроверять операции, которые обещаны пользователю
Ставят уведомление на один всплескМного ложных тревог, на уведомления перестают реагироватьДобавлять в правило длительность выполнения условия

§12Проверьте себя

Чем мониторинг отличается от ручной проверки сайта раз в день?

Мониторинг выполняет измерения регулярно и без участия человека, сохраняет их с отметкой времени и проверяет правила. Ручная проверка даёт одно наблюдение в один момент и не оставляет истории.

Первая реплика обработала 200 запросов, из них 20 с ошибкой. Вторая — 800 запросов, из них 20 с ошибкой. Какова общая доля ошибок?

(20 + 20) / (200 + 800) = 40 / 1000 = 4%. Среднее от 10% и 2,5% дало бы 6,25% — это неверно, потому что реплики обработали разное число запросов.

Загрузку CPU проверяют раз в минуту. Почему на графике может не оказаться всплеска, который длился 20 секунд?

Мгновенное значение фиксируется только в момент проверки. Если всплеск начался и закончился между двумя проверками, ни одна точка ряда его не содержит.

Ночью с 3:00 до 4:00 сервис не получил ни одного запроса. Что показать на панели доли ошибок?

«Нет данных». Знаменатель равен нулю, наблюдений нет, а 0% ошибок был бы ложным утверждением: так же выглядела бы и полная остановка сервиса.

Внешняя проверка сообщает, что сайт недоступен, а все внутренние показатели приложения в норме. Где искать проблему?

На пути от пользователя до приложения: доменное имя, сеть, сертификат, балансировщик. Внутренние показатели этот путь не видят, поэтому и остаются в норме.

§13Шпаргалка

  • Мониторинг: измерить → сохранить со временем → сопоставить → показать → отреагировать.
  • У показателя есть объект, величина, единица и способ расчёта.
  • Временной ряд — значения одной величины одного объекта, упорядоченные по времени.
  • Интервал измерения определяет, какие короткие события попадут в историю.
  • Доля = количество за окно / количество за то же окно. Для общей доли складывают количества.
  • Когда запросов нет, на панели пишут «нет данных»; 0% ошибок здесь неверно.
  • Четыре основных сигнала: задержка, трафик, ошибки, насыщение.
  • Проверка снаружи показывает, что пользователю плохо; показатели изнутри показывают место.
  • Правило оповещения: показатель, порог, длительность, получатель.

Первоисточники