Мониторинг сервисов в режиме реального времени для понимания текущих операционных показателей и состояния работоспособности сервисов является неотъемлемой частью микросервисной системы. Метрики, как важный компонент микросервисов, обеспечивают комплексную базу данных для мониторинга сервисов. Недавно была выпущена версия 2.0.1 Dubbo Metrics. Эта статья раскрывает происхождение Dubbo Metrics и 7 основных улучшений.

Истоки Dubbo Metrics

Dubbo Metrics (ранее Alibaba Metrics) — это широко используемая базовая библиотека классов для отслеживания метрик в Alibaba Group. Он имеет две версии: Java и Node.js. В настоящее время Java является версией с открытым исходным кодом. Построенная в 2016 году, внутренняя версия прошла почти трехлетнюю разработку и испытание шоппинг-карнавалом в «День холостяков». Он стал фактическим стандартом метрик мониторинга микросервисов в Alibaba Group, охватывающий все уровни метрик от системы, JVM, промежуточного программного обеспечения и до приложения, и сформировал единый набор спецификаций с точки зрения правил именования, форматов данных, отслеживания методы и правила вычислений.

Код Dubbo Metrics получен из Dropwizard Metrics и имеет номер версии 3.1.0. В то время две основные причины привели к решению создать внутренний форк для индивидуальной разработки.

Одна из причин заключается в том, что развитие сообщества идет очень медленно. Следующая версия была обновлена ​​на третий год после 3.1.0. Мы беспокоились, что сообщество не сможет вовремя отреагировать на потребности бизнеса. Другая более важная причина заключается в том, что в то время версия 3.1.0 не поддерживала многомерные теги и могла основываться только на традиционных методах именования метрик, таких как a.b.c. Это означает, что Dropwizard Metrics может выполнять измерения только в одном измерении. В реальном бизнес-процессе многие измерения невозможно определить заранее. А в крупномасштабной распределенной системе после завершения статистики данных данные необходимо агрегировать в соответствии с различными бизнес-измерениями, такими как агрегирование по центру обработки данных и группе, что в то время также не могло быть удовлетворено Dropwizard. . По разным причинам мы приняли решение форкнуть ветку для внутренней разработки.

Улучшения в метриках Dubbo

По сравнению с Dropwizard Metrics, Dubbo Metrics имеет следующие улучшения:

1. Введены правила именования на основе тегов

Как описано выше, многомерные теги имеют естественное преимущество перед традиционным методом именования метрик с точки зрения динамического отслеживания, агрегации данных и т.п. Например, чтобы вычислить количество вызовов и RT службы Dubbo с именем DemoService, ее обычно называют dubbo.provider.DemoService.qps и dubbo.provider.DemoService.rt на основе традиционного метода именования. Только для одного сервиса этот метод не представляет большой проблемы. Однако, если приложение микрослужбы предоставляет несколько служб Dubbo одновременно, сложно агрегировать QPS и RT для всех служб. Метрические данные по своей природе имеют атрибут временных рядов, поэтому данные могут быть соответствующим образом сохранены в базе данных временных рядов. Чтобы вычислить количество запросов в секунду для всех сервисов Dubbo, вам нужно найти все индексы с именем dubbo.provider.*.qps, а затем просуммировать их. Задействован нечеткий поиск, поэтому его реализация для большинства баз данных требует много времени. Если необходимо более подробно рассчитать QPS и RT уровня метода Dubbo, реализация будет более сложной.

  • Ключ метрики: строка, разделенная однобайтовыми точками, для обозначения значения этой метрики;
  • Тег метрики: для определения различных измерений сегментации этой метрики. Допускается использование одного или нескольких тегов;
  • Ключ тега: имя, используемое для описания измерения;
  • Значение тега: значение, используемое для описания измерения;

Учитывая, что все метрики, создаваемые всеми микросервисами компании, будут единообразно суммироваться на одной платформе для обработки, ключ метрики должен быть назван в соответствии с одним и тем же набором правил, чтобы избежать конфликтов имен, и формат appname.category[.subcategory]*.suffix

  • Appname: имя приложения;
  • Категория: категория этой метрики в этом приложении. Несколько слов соединены символом «_», а буквы в нижнем регистре;
  • Подкатегория: подкатегория этой метрики в определенной категории в этом приложении. Несколько слов соединены символом «_», а буквы в нижнем регистре;
  • Суффикс: ключевой суффикс, который может описывать конкретный тип, который может быть количеством, скоростью или распределением, измеряемым этой метрикой;

В предыдущем примере та же метрика может быть названа как dubbo.provider.service.qps{service="DemoService"}, где имя предыдущей части фиксировано и остается неизменным, а теги в скобках могут быть изменены динамически или даже добавлены дополнительные измерения. Например, после добавления измерения метода имя становится dubbo.provider.service.qps{service="DemoService",method="sayHello"}, а также можно добавить информацию об IP-адресе и центре обработки данных машины. Этот вид хранения данных совместим с базами данных временных рядов. На основе данных можно легко реализовать агрегацию, фильтрацию и другие операции в любом измерении.

Примечание. В конце декабря 2017 года Dropwizard Metrics 4.0 начал поддерживать теги, а реализация тегов в Dubbo Metrics основана на реализации в Dropwizard. И MicroMeter, и Prometheus, представленные в Spring Boot 2.0, также представили концепцию тегов.

2. Добавлена ​​функция точной статистики

Функция точной статистики Dubbo Metrics отличается от функции Dropwizard или других статистических библиотек отслеживания проектов с открытым исходным кодом. Это объясняется следующими двумя измерениями: выбором временного окна и статистическим методом пропускной способности.

В случае статистики пропускной способности (например, QPS) реализация Dropwizard представляет собой скользящее окно + экспоненциально взвешенное скользящее среднее (EWMA), предоставляя только 1 минуту, 5 минут и 15 минут выбора во временном окне.

Фиксированное окно против скользящего окна

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

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

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

Преимущество скользящего окна в том, что оно лучше работает в режиме реального времени. Статистическая информация во временном окне, выведенная вперед из текущего времени, может быть просмотрена в любое время. Относительно время сбора данных на разных машинах разное, поэтому данные на разных машинах необходимо агрегировать посредством так называемой Down-Sampling. То есть на основе фиксированного временного окна данные, собранные в этом окне, применяются к агрегатной функции. Например, если в кластере 5 машин и Down-Sampling выполняется по среднему значению с частотой 15 секунд. Если точка данных метрики собирается в 00:01, 00:03, 00:06, 00:09, 00:11 соответственно во временном окне 00:00~00:15, средневзвешенное значение этих 5 точек равно считается средним значением после понижающей выборки в 00:00.

Однако на практике раздвижные окна по-прежнему сталкиваются со следующими проблемами.

  • Во многих бизнес-сценариях требуются точные данные временного окна. Например, во время карнавала покупок в «День холостяков», если вы хотите узнать, сколько заказов создано в первую секунду в 0:00 этого дня, скользящее окно Dropwizard явно не применимо.
  • Окно, предоставляемое Dropwizard, находится только на уровне минут, но в этом сценарии оно должно быть точным до второго уровня.
  • Для агрегации данных кластера скользящие временные окна на каждой машине могут быть разными, а также может существовать временной интервал сбора данных, что приводит к неточным результатам агрегации.

Для решения этих проблем Dubbo Metrics предоставляет метрику BucketCounter, которая может точно вычислять данные на уровне минут и секунд, а временное окно может быть с точностью до 1 секунды. Точность результатов после агрегации кластера может быть гарантирована при условии, что время на каждой машине синхронизировано. Он также поддерживает статистику на основе скользящих окон.

Мгновенная ставка против экспоненциально-взвешенной скользящей средней (EWMA)

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

Например, если у вас есть микросервис и две машины, и метод генерирует 5 вызовов в течение определенного периода времени. Моменты времени этих вызовов — [5,17] на машине 1 и [6,8,8] на машине 2 соответственно (при условии, что единица измерения — миллисекунды). Если вы хотите вычислить среднее RT кластера, вы можете сначала вычислить среднее RT на одном компьютере, а затем вычислить общее среднее RT. В соответствии с этим методом среднее время восстановления машины 1 составляет 11 мс, а среднее время восстановления машины 2 — 7,33 мс. После того, как два снова усредняются, среднее время восстановления кластера составляет 9,17 мс. Но так ли это на самом деле?

Если данные на машинах 1 и 2 объединяются для вычисления, фактическое среднее значение RT составляет (5+17+6+8+8)/5 = 8,8 мс, что явно отличается от приведенного выше результата. Учитывая потерю точности при вычислении чисел с плавающей запятой и увеличение размера кластера, эта ошибка станет более очевидной. Таким образом, делается вывод, что пропускная способность на одной машине не имеет значения для вычисления пропускной способности кластера и имеет значение только для одной машины.

EWMA, предоставленный Dropwizard, также является средним, но также учитывает фактор времени. Чем ближе данные к текущему времени, тем выше будет вес данных. В случае, если времени достаточно, например, 15 минут, этот метод имеет смысл. Однако было замечено, что не имеет значения учитывать вес измерения времени в коротком временном окне, таком как 1 с и 5 с. Поэтому в процессе внутреннего обновления Dubbo Metrics была улучшена следующим образом:

  • Он может вычислять мгновенную скорость, чтобы отразить ситуацию с одним измерением машины, и удаляет средневзвешенное значение и использует метод простого среднего для вычисления;
  • Для агрегации кластера он предоставляет статистику общего количества вызовов и общего RT во временном окне, чтобы облегчить точное вычисление пропускной способности кластера;

3. Максимальная оптимизация производительности

В сценарии большого продвижения улучшение статистических показателей является важной темой для Dubbo Metrics. В бизнес-сценариях Alibaba число запросов в секунду статистического интерфейса может достигать десятков тысяч, например, сценарий доступа к кешу. Поэтому в данном случае горячей точкой может стать статистическая логика метрик. Мы сделали несколько целенаправленных оптимизаций:

В сценариях с высокой степенью параллелизма java.util.concurrent.atomic.LongAdder лучше всего справляется с накоплением данных, поэтому почти все операции в конечном итоге относятся к операциям над этим классом.

Избегайте вызова LongAdder#reset

Когда срок действия данных истекает, данные необходимо очистить. В предыдущей реализации LongAdder#reset использовался для очистки объекта для повторного использования. Однако фактический тест показывает, что LongAdder#reset на самом деле является операцией, потребляющей ресурсы ЦП. Поэтому память выбирается для замены ЦП, а новый объект LongAdder используется для замены LongAdder#reset при очистке.

Удалите операции избыточности и накопления

В реализациях некоторых метрик некоторые из них имеют больше статистических измерений, и несколько объектов LongAdder необходимо обновлять одновременно. Например, в метрической реализации Dropwizard Metrics вычисляется скользящее среднее за 1 минуту, 5 минут и 15 минут, и каждый раз необходимо обновлять 3 объекта LongAdder. Однако на самом деле эти 3 операции обновления повторяются и требуется только одно обновление.

Избегайте вызова метода добавления, когда RT равно 0

В большинстве сценариев RT измеряется в миллисекундах. Иногда, когда вычисленное значение RT составляет менее 1 мс, RT, переданное в метрики, равно 0. Однако было обнаружено, что собственный LongAdder JDK не оптимизирует операцию add(0). Даже если на входе 0, логика все равно повторяется, что по существу вызывает sun.misc.Unsafe.UNSAFE.compareAndSwapLong. В это время, если метрика определяет, что операция добавления не выполняется для счетчика, когда RT равно 0, то одну операцию добавления можно пропустить. Это очень полезно для ПО промежуточного слоя с высокой степенью параллелизма, такого как распределенный кеш. В ходе внутреннего тестирования приложения мы обнаружили, что в 30% случаев RT для доступа к распределенному кешу составляет 0 мс. Эта оптимизация может исключить множество бессмысленных операций обновления.

Выполнение комбинированной статистики по QPS и RT

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

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

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

Но не забывайте, что, помимо количества вызовов, нужно вычислить еще и RT выполнения метода. Можно ли еще уменьшить?

Ответ - да! Предполагая, что RT вычисляется в миллисекундах, мы знаем, что 1 объект Long имеет 64 бита (на самом деле объект Long в Java подписан, поэтому теоретически доступны только 63 бита), в то время как статистический цикл метрик вычисляет только 60-секундные данные в большинство, поэтому эти 64 бита все равно не могут быть израсходованы. Можем ли мы разделить эти 63 бита и одновременно вычислить счетчик и RT? На самом деле это осуществимо.

Мы используем старшие 25 битов из 63 битов объекта Long для представления общего количества в статистическом цикле, а младшие 38 битов — для представления общего RT.

------------------------------------------
|   1 bit    |     25 bit   |     38 bit |
| signed bit |  total count |   total rt |
------------------------------------------

Когда поступает вызов, предполагая, что переданное RT равно n, то число, накапливаемое каждый раз, равно не 1 или n, а

1 * 2^38 + n

Этот дизайн в основном имеет следующие соображения:

  • Count увеличивается на 1 для каждого вызова, а RT увеличивается на N для каждого вызова. Если count находится в старшем бите, добавьте 1 для каждого вызова, что на самом деле является фиксированной константой, но если RT находится в старшем бите, контент, добавляемый для каждого вызова, отличается, поэтому его следует вычислять каждый раз;
  • 25 бит могут представлять не более 2²⁵=33554432 чисел, поэтому он точно не переполнится для статистики вызовов методов в течение 1 минуты.
  • RT может быть относительно большим, поэтому младший бит равен 38 битам, представляющим 2³⁸=274877906944 чисел, что в принципе невозможно переполнить.

Что, если он переполнится?

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

Ведро без замкаСчетчик

В предыдущем коде BucketCounter должен гарантировать, что только один поток обновляет Bucket при многопоточном параллельном доступе, поэтому он использует блокировку объекта. В последней версии BucketCounter был перереализован, сняв блокировку с исходной реализации и работая только с AtomicReference и CAS. Таким образом, локальное тестирование показало, что производительность увеличилась примерно на 15%.

4. Полная метрическая статистика

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

Операционные системы

Он поддерживает Linux, Windows и Mac, включая CPU, Load, Disk, Net Traffic и TCP.

JVM

Он поддерживает загрузку классов, время и время GC, дескрипторы файлов, занятость области Young/Old, статус потока, память вне кучи, время компиляции, а некоторые метрики поддерживают автоматическое вычисление разницы.

ПО промежуточного слоя

Tomcat: количество запросов, количество сбоев, время обработки, количество отправленных и полученных байтов и количество активных потоков в пуле потоков;

Druid: количество выполнений SQL, количество ошибок, время выполнения и количество затронутых строк;

Nginx: прием, активные подключения, количество запросов на чтение и запись, количество очередей, QPS запроса и среднее время восстановления.

Более подробные показатели см. здесь. Поддержка Dubbo, NACOS, Sentinel и Fescar будет добавлена ​​позже.

5. Поддержка ОТДЫХА

Dubbo Metrics предоставляет доступ к интерфейсу REST на основе JAX-RS, который упрощает запрос различных внутренних показателей. Он может запускать HTTP-сервер для предоставления услуг самостоятельно (по умолчанию предоставляется простая реализация на основе Http-сервера Jersey + sun) или встраивать существующий HTTP-сервер для предоставления метрик. Для конкретных интерфейсов см.:

https://github.com/dubbo/metrics/wiki/запрос-от-http

6. Данные одной машины записаны на диск

Если все данные хранятся в памяти, возможна потеря данных из-за сбоя извлечения или дрожания приложения. Чтобы решить эту проблему, metrics представила модуль, который обеспечивает два режима, режим журнала и двоичный режим, для записи данных на диск.

  • По умолчанию режим журнала выполняет вывод через JSON. Выходные данные могут быть извлечены и агрегированы компонентом журнала. Читабельность файла относительно высока, но исторические данные не могут быть запрошены.
  • Двоичный режим обеспечивает более компактное хранение и поддерживает запросы к историческим данным. Этот режим в настоящее время используется внутри компании.

7. Оптимизация для удобства использования и стабильности

  • API и реализация отслеживания разделены, чтобы облегчить интеграцию различных реализаций, не требуя от пользователей внимания;
  • Поддерживается отслеживание через аннотацию;
  • Он опирается на структуру лог-фреймворка, что делает более удобным получение метрик.
  • Compass и FastCompass добавлены для облегчения общего отслеживания для предприятий, например статистики QPS, RT, процента успешных попыток, количества ошибок и других показателей;
  • Spring Boot Starter скоро будет с открытым исходным кодом. Пожалуйста, не переключайтесь;
  • Поддерживается автоматическая очистка метрик, чтобы не занимать память давно неиспользуемыми метриками;
  • Метрики URL-адресов объединены, и реализована максимальная защита, чтобы предотвратить использование памяти, вызванное взрывом измерений и статистикой ошибок.

Инструкции по использованию

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

Counter hello = MetricManager.getCounter("test", MetricName.build("test.my.counter"));
hello.inc();

Поддерживаемые показатели включают:

  • Прилавок
  • Meter (показатель пропускной способности)
  • Гистограмма (показатель распределения гистограммы)
  • Gauge (показатель переходного значения)
  • Таймер (показатель пропускной способности и распределения времени отклика)
  • Компас (показатель пропускной способности, распределения времени отклика, коэффициента успеха и кода ошибки)
  • FastCompass (метрика для быстрой и эффективной статистики пропускной способности, среднего времени отклика, успешности и кода ошибки)
  • ClusterHistogram (метрика кластерного квантиля)

Будущие работы

  • Предоставить Spring Boot Starter.
  • Для поддержки Prometheus и Spring MicroMeter.
  • Интегрировать Dubbo и заменить реализацию статистики данных в Dubbo на Dubbo Metrics.
  • Для отображения различных данных метрик в Dubbo Admin.
  • Интегрировать другие компоненты в экосистему Dubbo, такие как NACOS, Sentinel и Fescar.

использованная литература

Даббо Метрикс @Github:

https://github.com/dubbo/metrics

Вики:

https://github.com/dubbo/metrics/wiki (постоянное обновление)

Об авторах

Ван Тао (идентификатор GitHub @ralf0131) — член Apache Dubbo PPMC, член Apache Tomcat PMCM и технический эксперт Alibaba.

Цзы Гуан (GitHub id@min) — коммитер Apache Dubbo и старший инженер-разработчик в Alibaba, который отвечает за разработку проектов Dubbo Admin и Dubbo Metrics, а также за обслуживание сообщества.

Оригинальный источник

https://www.alibabacloud.com/blog/dubbo-metrics-exploring-the-measurement-and-statistics-infrastructure-of-dubbo_594892?spm=a2c41.13014816.0.0