В этом посте я расскажу про мониторинг — процесс сбора и анализа информации для принятия обоснованных управленческих решений и достижения показателей назначения. Начну с того, насколько стоит погружаться в мониторинг разным командам, вспомню основные методологии и две важнейшие, на мой взгляд, метрики, с которыми можно покрыть все (или почти все) кейсы.
Мониторинг — одна из трех частей концепции Observability (наблюдаемость), в которой описаны методы получения доступа к информации о внутреннем состоянии системы. Помимо мониторинга, концепция также включает логирование и трассировку.
Мониторинг часто путают с логированием, но эти понятия разделяют не просто так. При логировании мы работаем с логами — потоком событий. А при мониторинге мы собираем, оцифровываем и агрегируем определенную информацию, необходимую для принятия решений. Для полноты картины дадим определение трассировке — это наблюдение за обменом информацией между системами через запросы с помощью ServiceMesh или других инструментов.
Приведу простой пример мониторинга. У нас есть база данных, и пользователи говорят, что она тормозит. Мы смотрим результаты мониторинга базы данных: примерно 1000 запросов в секунду со средним временем ответа в 2 секунды. Хорошо это или плохо, нам подскажут показатели назначения. Представим, что там указано время ответа в 1 секунду при 1000 запросов. Как прийти к этим показателям? Можно добавить аппаратных ресурсов, оптимизировать запросы, сделать шардинг или придумать что-нибудь еще. Выбрать лучший вариант нам тоже поможет мониторинг.
Многие IT-системы внедряются как «черный ящик», поэтому решения по поводу их дальнейшего развития принимают по наитию, по каким-то внутренним ощущениям. Но какой бы ни была IT-система, мониторинг в ней предусмотреть можно. Глобально здесь выделяют три больших направления:
Железо. Какие бы облака мы ни использовали, в их основе всегда лежит аппаратная конфигурация, которую стоит мониторить по загрузке и другим важным параметрам.
Инфраструктура. Здесь может быть много слоев со своими наборами метрик — например, база данных, Kafka и другие инфраструктурные сервисы. Для полноценного мониторинга нужно учитывать их все.
Прикладные сервисы. Мы пишем их сами и метрики для них тоже определяем сами. Они должны быть понятны для всех, а не только для тех, кто их придумал.
Роль мониторинга в командах
Глубже всего в мониторинг стоит погружаться девопсам и SRE. В их задачи входит организация и сбор метрик по железу и инфраструктуре. Уровень прикладных сервисов они так проработать не смогут. Для девопсов это черный ящик, который, максимум, можно обернуть стандартными сервисами: например, если это HTTP-сервис, то при балансировке через nginx к нему можно прикрутить стандартные метрики.
Разработчикам стоит понимать, какие метрики по оборудованию и инфраструктуре необходимы для их задач. Вот, например, накодили вы систему, на нагрузочном тестировании всё было гладко, а в итоге ничего не работает. Но нашелся коллега, который разбирается в метриках БД, и помог раскрутить клубок: оказывается, вы просто забыли оптимизировать запросы в БД, поставить индексы. Поэтому индексы перестали влезать в оперативную память, БД пришлось лезть на диск и делать full-table сканы, а это привело к плачевному итогу. Кроме умения смотреть важно также умение организовать нормальный сбор метрик в своем коде — иначе он превратится в черный ящик из прошлого абзаца.
QA и саппорт должны обязательно понимать метрики прикладных сервисов, а на более глубоких уровнях можно обратиться к инженерам. Это же справедливо и для продакт-менеджеров, и для продакт-оунеров: метрики приклада стоит понимать всем.
Методики мониторинга
Начинающие разработчики, бывает, пасуют перед задачами мониторинга, поскольку не знают, как к ним подойти. Далее я вкратце расскажу о трех стандартных методиках, которые стоит выделить — USE, RED и The Four Golden Signals. Они помогают четко понять, что и как нужно мониторить.
USE расшифровывается как Utilization, Saturation, Error. USE подходит для мониторинга ограниченных ресурсов, например, оборудования. В общих чертах это выглядит так:
Utilization — работа под нагрузкой.
Saturation — работа под сверхнагрузкой (задачи в очереди).
Errors — количество ошибок.
Переложим эти USE-метрики для процессора:
Utilization. Здесь нас могут интересовать четыре метрики процессорного времени: idle (сколько процессор не используется), iowait (сколько процессор ждет I/O), system (сколько уходит на систему), user (сколько — на пользовательские задачи). Учтите, что в сумме эта метрика не может превышать общее количество процессорного времени,
Saturation. LA (LoadAverage) — с помощью нее мы оцениваем, насколько используется многоядерная система. Если это значение больше, чем количество ядер в конфигурации, то задачи складываются в бэклог.
Errors. Cache misses — количество ошибок кэша
Аналогично можно измерять не только аппаратные ресурсы, но и вообще любые ограниченные ресурсы внутри приложения, например, буферы, кэши, пулы соединений. В последнем случае метрики будут выглядеть примерно так:
Utilization: сколько соединений выделено, сколько используется.
Saturation: количество ожидающих запросов на соединение. Если их 0, то у нас, скорее всего, есть свободные соединения.
Errors: сколько раз по разным причинам мы не смогли установить соединение.
RED означает Rate, Errors, Duration. Это совсем другой метод, который лучше всего подходит в кейсах с неограниченными ресурсами, особенно для приложений в режиме request-response:
Rate — количество запросов к ресурсу в единицу времени
Errors — количество запросов в единицу времени, закончившихся ошибкой
Duration — время выполнения запроса (в виде гистограммы)
The Four Golden Signals не складываются в аббревиатуру, чтобы упростить запоминание. Но частично эта методика также пересекается с предыдущими. Четыре золотых сигнала рекомендуют для использования с фронтендом:
Latency — задержки. Здесь важно разделять задержи успешных и неудачных запросов; последние могут испортить общую статистику.
Traffic — загруженность системы. В веб-сервисах, например, обычно измеряется в количестве HTTP-запросов в секунду.
Errors — ошибки. Доля запросов, которые по разным причинам завершились ошибками.
Saturation — уровень загруженности системы. Особое внимание здесь стоит уделить ресурсам, которые ограничены. Также, производительность некоторых систем падает еще до достижения полной загрузки, поэтому стоит заранее определить целевой уровень.
Разрезы метрик
Создавая метрики, важно учитывать их разрезы — то, как их можно представить в совокупности для определенных целей. Продолжим на примере методологии RED. В случае с HTTP-запросами можно делать разрезы по определенному пути, методу или ответу.
Выше представлен пример подобного разреза по исключениям, методам, статусам и другим параметрам. Что здесь не учитывается? Время. Много раз я видел, как разработчики пытаются во время мониторинга извлекать метки времени и колдовать над ними: собирать средние значения, строить графики, какие-то медианные и прочее. Делать этого не надо. Для подобных задач предусмотрены гистограммы.
В примере выше время запроса измеряется монотонно растущим счетчиком. Создается куча бакетов с тегом “le” — less than or equal. Внутри бакета работает счетчик запросов, попавших в интервал бакета. Все запросы, занимающие больше 30 секунд, попадают в “le=+inf”. Так мы можем не привязываться ко времени, а сразу распределять запросы. Самостоятельно прописывать эту логику не надо: у Micrometer, например, для этого есть отдельный класс timer, аналогичные инструменты предусмотрены в JS, Grafana и еще много где.
Интерпретируются результаты здесь в виде перцентилей. Например, 99% запросов попадают в одно время, 95% — в другое и так далее. Обычно достаточно четырех перцентилей, чтобы сделать вывод о системе.
Когда вы откроете для себя прелести мониторинга, может возникнуть соблазн насоздавать как можно больше метрик. Увлекаться здесь не стоит, ведь каждую метрику впоследствии предстоит поддерживать и уметь интерпретировать. Для фоновых задач лучше вообще использовать одну метрику с тегами, например, job_rate{job = “send”} и job_rate{job = “receive”}. С помощью тегов здесь можно будет динамически конфигурировать дашборды Grafana.
Великая универсальная метрика
Большую часть задач мониторинга можно решить одной-единственной метрикой — counter (монотонно растущий счетчик). С помощью этого счетчика можно посчитать очень много всего, например Rate — инкремент в секунду. Мы можем запросить его в любом нужном нам разрезе, с разными условиями.
Еще одна замечательная черта этой метрики: ее можно складывать между разными инстансами в кластере. Да и гистограмма времени по сути также представляет собой монотонно растущий счетчик. В целом 90% задач мониторинга можно решить с помощью монотонно растущего счетчика. И тегов, разумеется.
Вторая универсальная метрика
Другая универсальная метрика — это gauge, значение в моменте. Этот вариант больше подходит для бизнес-метрик и значений из БД. Gauge — очень агрегированная метрика, ее трудно делить на теги, поэтому нужно использовать ее очень аккуратно, при одинаковых значениях у всех экземпляров в кластере (например, количества записей в БД).
Gauge решает те 10% задач мониторинга, которые не решает counter. Например, через gauge можно выводить текущий размер какой-либо очереди, а с помощью counter тем временем — количество прочитанных и записанных в этой очереди сообщений. Этого набора будет достаточно для мониторинга любой очереди. Аналогично мы можем мониторить жизненный цикл любых бизнес-процессов.
Что мониторить? Всё!
Бывает, что при мониторинге упускают фоновые процессы, но мониторить их очень важно. HTTP-метрики можно снимать с nginx, а метрики задач придется делать самостоятельно, поскольку они специфичны для приложения. Можно также использовать метрики, которые экспортирует, например, Quartz.
Выделю здесь также этапы исполнения бизнес-процесса. Но если у нас, например, есть 20 типов заявок и 30 статусов, не нужно делать для этого 600 метрик. Просто считайте через инкрементные счетчики переходы заявок между статусами, и далее вы сможете построить любые необходимые отчеты.
Важно мониторить все внешние вызовы — нужно понимать, как долго нам отвечают, на сколько запросов, сколько ошибок получаем. Без этого придется бесконечно анализировать логи. И конечно, не стоит забывать о размерах очередей — их мы разбирали выше.
Настраивая мониторинг, важно не изобретать велосипед. Все необходимое обычно уже доступно бесплатно. Kafka умеет мониториться из коробки. HTTP-сервера и клиенты тоже могут экспортировать метрики — нужно только подключить их и вывести. Та же ситуация и с фоновыми процессами.
Почему это важно?
В среднем любая система пишется 10%, а эксплуатируется 90% времени. Чем больше людей вовлечено в работу с ней, тем больше времени нужно уделить мониторингу. С помощью метрик разработчики смогут быстрее понять, что сломано на проде. А с помощью хороших метрик — еще и почему сломано. Особенно это спасает с внешними интеграциями.
В распределенных системах типа блокчейна наблюдаемость в целом приобретает еще большее значение (помните термин Observability из начала поста?). Здесь у нас имеется много сред, много переменных и вариантов, что может пойти не так. Время поиска проблемы и всех проверок растет экспоненциально. Также мониторинг помогает понять, какие точки в системе хрупкие, оцифровать эту «хрупкость» и показатели производительности системы.