Микрометрики для прогнозирования производительности приложений

Прогнозируется даже непредсказуемая погода. Но после всех этих технологических достижений, можем ли мы прогнозировать производительность и доступность наших приложений? Можем ли мы прогнозировать даже на следующие 20 минут? Сможете ли вы сказать, что в следующие 20 минут приложение будет испытывать OutOfMemoryError, всплески процессора, сбои? Скорее всего нет. Это потому, что мы ориентируемся только на макрометрики:

  • Использование памяти
  • Время отклика
  • Загрузка процессора

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

ПРИМЕР: 1

куча-граф.PNG
Рис. Вы можете заметить повторяющиеся запуски полных сборщиков мусора (график с сайта GCeasy.io)

Давайте начнем это обсуждение с примера. В этом приложении возникла ошибка OutOfMemoryError. Посмотрите на график использования кучи (созданный путем разбора журналов сборки мусора). Вы можете заметить, что использование кучи становится все выше и выше, несмотря на то, что полные сборщики мусора выполняются постоянно. Это приложение столкнулось с ошибкой OutOfMemoryError около 10:00, в то время как повторные полные сборщики мусора начали происходить примерно в 08:00. С 08:00 до 10:00 заявка выполняла только повторные полные GC. Если бы команда DevOps отслеживала действия по сбору мусора, они должны были бы предсказать, что приложение столкнется с ошибкой OutOfMemoryError даже за пару часов до этого.

Микрометрические показатели, связанные с памятью
Существует 4 микрометрики, связанные с памятью/сборкой мусора, которые вы можете отслеживать:

1.Сборка мусора Пропускная способность
2.Сборка мусора Время паузы
3. Скорость создания объекта
4. Максимальный размер кучи

Давайте обсудим их в этом разделе.

Сбор мусора — это количество времени, которое приложение тратит на обработку транзакций клиентов, по сравнению с количеством времени, которое приложение тратит на сборку мусора.

Допустим, ваше приложение работает уже 60 минут. В этих 60 минутах 2 минуты тратятся на действия GC.

Это означает, что приложение потратило 3,33% на действия GC (т.е. (2/60) * 100).

Это означает, что пропускная способность сборки мусора составляет 96,67% (т.е. 100 – 3,33).

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

кпи.PNG
Рис. Микрометрические показатели пропускной способности сборщика мусора и задержки сборщика мусора

Когда выполняются определенные этапы события сборки мусора, все приложение приостанавливается. Эта пауза называется задержкой. Некоторые события сборки мусора могут занимать несколько миллисекунд, тогда как некоторые события сборки мусора могут занимать от нескольких секунд до нескольких минут. Вам необходимо отслеживать время пауз GC. Если время паузы GC начнет увеличиваться, это повлияет на работу пользователя.

объект-статистика.PNG
Рис. Микрометрическая скорость создания объектов

Скорость создания объектов — это среднее количество объектов, созданных вашим приложением. Скажем, предположим, что ваше приложение было 100 МБ/сек. А в последнее время начинает выдавать 150мб/сек без увеличения объема трафика — значит, это признак того, что в приложении назревает какая-то проблема. Эта дополнительная скорость создания объектов может привести к увеличению активности GC, увеличению потребления ресурсов ЦП и снижению времени отклика.

Вы можете использовать эту же метрику в конвейере CI/CD для измерения качества фиксации кода. Скажем, в вашей предыдущей фиксации кода ваше приложение создавало 50 МБ/с. Начиная с недавней фиксации кода, скажем, ваше приложение начинает создавать 75 МБ/с для такого же объема трафика — тогда это указывает на неэффективную фиксацию кода в вашем репозитории.

jvm-heapsize.PNG
Рис. Пиковый размер кучи, микрометрический

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

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

(1). Вы можете включить журналы сборки мусора, передав следующие аргументы JVM:

Для Java 8:

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:

Из Java 9:

-Xlog:gc*:файл=

(2). После создания журналов сборки мусора вы можете либо вручную преобразовать журналы GC в инструменты анализа журнала GC, такие как fastThread.io, либо с помощью программного REST API. REST API полезен, если вы хотите автоматизировать процесс создания отчетов. Его также можно использовать в конвейере CI/CD.

ПРИМЕР 2
Через несколько часов после запуска в крупном финансовом приложении возникла ошибка «OutOfMemoryError: невозможно создать новый собственный поток». Это приложение включило новую функцию в драйвере JDBC (Java Database Connectivity). Судя по всему, в этой фиче была ошибка, из-за которой JDBC-драйвер начинал многократно создавать новые потоки (вместо повторного использования одних и тех же потоков). Таким образом, в течение короткого промежутка времени приложение начало испытывать «OutOfMemoryError: невозможно создать новый собственный поток». Если бы команда отслеживала количество и состояние потоков, они могли бы обнаружить проблему на раннем этапе и предотвратить сбой. Вот фактические дампы потоков, полученные из приложения. Вы можете заметить, что количество потоков в состоянии RUNNABLE увеличивается между каждым дампом потока с течением времени.

количество потоков.PNG
Рис. Рост количества потоков в состоянии RUNNABLE (график из fastThread.io)

Микрометрические показатели резьбы
Существует 4 микрометрики, связанные с потоком, которые вы можете отслеживать:

  • Число потоков
  • Состояния потока
  • Группы тем
  • Шаблоны выполнения потоков
    Давайте обсудим их в этом разделе.

Количество потоков — интересная метрика для мониторинга. Если количество потоков превышает лимит, это может вызвать проблемы с процессором, памятью и сбои приложений. Слишком много потоков может вызвать ошибку java.lang.OutOfMemoryError: невозможно создать новый собственный поток. Таким образом, если количество потоков в приложении продолжает увеличиваться, это может свидетельствовать о какой-то назревающей проблеме в приложении.

поток-состояние.PNG
Рис. Состояние резьбы микрометрическое

Потоки приложения могут находиться в 6 разных состояниях: НОВОЕ, РАБОТАЕТ, ОЖИДАНИЕ, TIMED_WAITING, БЛОКИРОВАНО, ПРЕКРАЩЕНО. Слишком много потоков в состоянии RUNNABLE может вызвать всплеск загрузки ЦП. Слишком много потоков в состоянии BLOCKED может привести к тому, что приложение не будет отвечать на запросы. Если количество потоков в определенном состоянии потока превышает типичный порог вашего приложения, это является ранним признаком того, что в вашем приложении накапливается угроза производительности.

поток-группа.PNG
Рис. Микрометрическая группа резьбы

Группа потоков — это набор потоков, выполняющих схожие задачи. Может существовать группа потоков контейнера сервлетов, которая обрабатывает все входящие HTTP-запросы. Может быть группа потоков JMS, которая обрабатывает все операции отправки и получения JMS. В приложении могут быть и другие конфиденциальные группы потоков. Вы контролируете размер этих групп потоков. Вы не хотите, чтобы их размер ни опускался ниже порога, ни превышал порог. Меньшее количество потоков в группе потоков может привести к остановке действий. Большее количество потоков может привести к проблемам с памятью и процессором.

идентичная потоку-stacktrace.PNG
Рис. Потоки с идентичной трассировкой стека

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

(а). Допустим, ваш SOR или внешний сервис замедляется, тогда значительное количество потоков начнет ждать его ответа. В таком случае эти потоки будут иметь одинаковую трассировку стека.

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

(с). Если условие цикла (цикл for, цикл while, цикл do..while) не завершается, тогда несколько потоков, выполняющих этот цикл, будут иметь одинаковую трассировку стека.

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

Как сгенерировать микрометрику, связанную с потоком?
Все микрометрики, связанные с потоком, можно получить из дампа потока:

(1). Существует несколько вариантов захвата дампа потока из вашего приложения. Вы можете выбрать удобный для вас вариант. Желательно снимать дампы потоков через 5-10 секунд для проведения анализа.

(2). После создания дампов потоков вы можете либо вручную проанализировать их с помощью инструментов анализа дампов потоков, таких как fastThread.io, либо с помощью программного REST API. REST API полезен, если вы хотите автоматизировать процесс создания отчетов. Его также можно использовать в конвейере CI/CD.

Сетевые микрометрики
Есть 3 микрометрики, связанные с сетью, на которых вы можете сосредоточиться:

  • Количество подключений TCP/IP по узлам
  • Состояния TCP/IP
  • Дескрипторы открытых файлов
    Давайте обсудим их в этом разделе.

Современное приложение подключается к нескольким внешним приложениям (излишне говорить о мире микросервисов, где слишком много внешних подключений). Соединения устанавливаются по различным протоколам: HTTP, HTTPS, SOAP, REST, JDBC, JMS, Kafka… В такой экосистеме скорость отклика и доступность вашего приложения также зависят от доступности и скорости отклика внешних приложений. Таким образом, вам необходимо отслеживать количество подключений, установленных из вашего приложения к внешним приложениям. Если вы видите, что количество подключений растет больше, чем обычно, это может быть проблемой. Всякий раз, когда во внешнем приложении происходит замедление, ваше приложение может открывать все больше и больше подключений к внешнему приложению для обработки входящих транзакций.

Вы можете узнать количество установленных подключений к внешним системам с помощью команды «netstat», как показано ниже:

$ netstat -an | grep ESTABLISHED | grep '162.187.223.11' | wc -l

Приведенная выше команда покажет количество установленных подключений к хосту «162.187.223.11».

Существует 11 различных состояний TCP/IP: LISTEN, SYN-SENT, SYN-RECEIVED, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT, CLOSED. Вам необходимо отслеживать количество подключений в каждом состоянии каждой внешней системой, к которой подключается ваше приложение. Если вы заметите, что счетчик определенного состояния начинает расти, например, CLOSE-WAIT или LAST-ACK…, то это может указывать на то, что в приложении назревает какая-то проблема с сетевым подключением.

$ netstat -an | grep 'TIME_WAIT' | wc -l

Вышеприведенная команда показывает количество подключений в состоянии «TIME_WAIT». Точно так же вы можете выполнить grep и для других состояний.

Файловый дескриптор — это дескриптор доступа

(а). Файл

(б). Pipe (это механизм межпроцессного взаимодействия с использованием передачи сообщений, т. е. ls -l | grep key | less)

(с). Сетевые соединения.

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

Команда ниже сообщит обо всех дескрипторах открытых файлов для процесса с идентификатором «5666».

lsof -p 5666

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

$ lsof -p 5666 | wc -l
153

Микрометрические показатели, связанные с хранилищем
Есть 3 микрометрики, связанные с хранилищем, на которых вы можете сосредоточиться:

*IOPS
* Пропускная способность хранилища
*Задержка хранилища
Давайте обсудим их в этом разделе.

Операций ввода-вывода в секунду, что означает количество операций чтения или записи, которые можно выполнить за одну секунду. Для определенных операций ввода-вывода размер запроса ввода-вывода может быть очень маленьким. Примеры размера ввода-вывода могут быть 4 КБ, 8 КБ, 32 КБ и т. д. Таким образом, большие размеры запросов ввода-вывода могут означать меньшее количество операций ввода-вывода в секунду.

Пропускная способность хранилища — это обычное значение, которое показывает, сколько может предоставить хранилище. Это число обычно выражается в мегабайтах в секунду (МБ/с), например 140 МБ/с. Ниже приведены формулы для получения пропускной способности.

Средний размер операций ввода-вывода x IOPS = пропускная способность в МБ/с

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

Микрометрика, связанная с базой данных
В этой статье рассматриваются только микрометрики прикладного уровня. Однако мониторинг микрометрики базы данных также может быть плодотворным. Вот список микрометрик, которые можно отслеживать в БД:

Вывод
Эти микрометрические показатели можно отслеживать в производственной среде для прогнозирования проблем с пивоварением. Кроме того, их можно использовать в конвейере CI/CD для контроля качества кода.

Мы надеемся, что вы найдете эту микрометрику полезной. Если вы считаете, что существуют более мощные микрометрики, которые могут прогнозировать производительность приложения, напишите нам по адресу team@tier1app.com. Мы будем рады дополнить эту статью указанными вами показателями.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *