Когда вы запускаете долгосрочные приложения, такие как веб-приложения, полезно знать некоторую статистику о них, например, количество обработанных запросов, длительности запросов или количество активных запросов.
Но также некоторую более общую информацию, такую как состояние ваших внутренних коллекций, сколько раз выполняется какая-то часть кода, или проверки работоспособности, такие как доступность базы данных, или любой вид соединения с внешней системой.
Все эти виды инструментализации могут быть достигнуты с помощью нативного JMX или модульного проекта, такого как Metrics . Метрики предоставляют эффективный способ измерить поведение ваших критических компонентов и сообщить о них различным системам, таким как JConsole , System Console , Ganglia , Graphite , CSV , или сделать их доступными через веб-сервер. Чтобы установить метрики , нам нужно только добавить метрики зависимости. В этом примере мы будем использовать Maven.
1
2
3
4
5
6
7
|
<span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" ><dependencies></span> <Зависимостей></span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" ><dependency></span> <Зависимость></span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" ><groupId>com.yammer.metrics</groupId></span> <Идентификатор_группы> com.yammer.metrics </ идентификатор_группы></span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" ><artifactId>metrics-core</artifactId></span> <Артефакт> Метрика-ядро </ артефакт></span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" ><version> 2.2 . 0 </version></span> <Версия> 2.2 . 0 </ версия></span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" ></dependency></span> </ Зависимость></span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" ></dependencies></span> </ Зависимости></span> |
Теперь пришло время добавить некоторые метрики в наш код. В метриках мы можем использовать 6 типов метрик:
- Датчики : мгновенное измерение дискретного значения.
- Счетчики : значение, которое можно увеличивать и уменьшать. Может использоваться в очередях для мониторинга оставшегося количества ожидающих заданий.
- Метры : измерьте скорость событий с течением времени. Вы можете указать единицу тарифа, объем событий или тип события.
- Гистограммы : измерение статистического распределения значений в потоке данных.
- Таймеры : измеряют количество времени, необходимое для выполнения фрагмента кода, и распределение его продолжительности.
- Проверка работоспособности : как следует из его названия, она централизует проверку работоспособности внешних систем нашей службой.
Итак, давайте напишем действительно простое приложение (на самом деле это консольное приложение), которое отправляет запросы в поисковую систему Google . Мы измерим количество петиций, количество символов, отправленных в Google , последнее найденное слово и таймер для измерения скорости отправки запроса и получения ответа.
Основной класс, в котором будут применяться меры , называется MetricsApplication и отвечает за подключение к Google и отправку введенного слова.
1
|
<span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > public class MetricsApplication { Counter private final Counter numberOfSendCharacters = Metrics.newCounter(MetricsApplication. class , 'Total-Number-Of-Characters' );</span> открытый класс MetricsApplication {Счетчик закрытого конечного счетчика numberOfSendCharacters = Metrics.newCounter (MetricsApplication. class , «Общее количество символов»);</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >Meter private final Meter sendMessages = Metrics.newMeter(MetricsApplication. class , 'Sent-Messages' , 'Send' , TimeUnit.SECONDS);</span> Meter private final Meter sendMessages = Metrics.newMeter (MetricsApplication. class , 'Sent-Messages' , 'Send' , TimeUnit.SECONDS);</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >Timer private final Timer responseTime = Metrics.newTimer(MetricsApplication. class , 'Response-Time' );</span> Таймер приватный окончательный Таймер responseTime = Metrics.newTimer (MetricsApplication. class , 'Response-Time' );</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > private LinkedList<String> historyOfQueries = new LinkedList<String>();</span> private LinkedList <String> historyOfQueries = new LinkedList <String> ();</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >{ Gauge Metrics.newGauge(MetricsApplication. class , 'lastQuery' , new Gauge<String>() { @Override public String value() { return historyOfQueries.getLast(); } });</span> {Gauge Metrics.newGauge (MetricsApplication. class , 'lastQuery' , new Gauge <String> () { @Override public String value () { return historyOfQueries.getLast ();}});</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >} public void sendQuery(String message) throws FailingHttpStatusCodeException, MalformedURLException, IOException { updateMetrics(message);</span> } public void sendQuery (String message) выдает FailingHttpStatusCodeException, MalformedURLException, IOException {updateMetrics (message);</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >TimerContext timerContext = responseTime.time();</span> TimerContext timerContext = responseTime.time ();</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >sendQueryToGoogle(message);</span> sendQueryToGoogle (сообщение);</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >timerContext.stop();</span> timerContext.stop ();</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >} private void sendQueryToGoogle(String message) throws FailingHttpStatusCodeException, MalformedURLException, IOException { WebClient webClient = new WebClient();</span> } private void sendQueryToGoogle (String message) выдает FailingHttpStatusCodeException, MalformedURLException, IOException {WebClient webClient = new WebClient ();</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >HtmlPage currentPage = webClient.getPage( 'http:www.google.com' );</span> HtmlPage currentPage = webClient.getPage ( 'http: www.google.com' );</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >Get the query input text HtmlInput queryInput = currentPage.getElementByName( 'q' );</span> Получить входной текст запроса HtmlInput queryInput = currentPage.getElementByName ( 'q' );</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >queryInput.setValueAttribute(message);</span> queryInput.setValueAttribute (сообщение);</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >Submit the form by pressing the submit button HtmlSubmitInput submitBtn = currentPage.getElementByName( 'btnG' );</span> Отправьте форму, нажав кнопку отправки. HtmlSubmitInput submitBtn = currentPage.getElementByName ( 'btnG' );</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >currentPage = submitBtn.click();</span> currentPage = submitBtn.click ();</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >} private void updateMetrics(String message) { numberOfSendCharacters.inc(message.length());</span> } private void updateMetrics (String message) {numberOfSendCharacters.inc (message.length ());</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >sendMessages.mark();</span> sendMessages.mark ();</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >historyOfQueries.addLast(message);</span> historyOfQueries.addLast (сообщение);</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >} }</span> }}</span> |
Первое, что мы видим, это контрпример. Этот счетчик будет подсчитывать количество символов, отправленных в Google за всю жизнь приложений (пока вы не остановите это).
Следующее свойство — это индикатор, который измеряет скорость отправки запросов с течением времени. Затем у нас есть таймер, который оценивает вызовы метода sendQueryToGoogle и его распределение по времени. И, наконец, LinkedList для хранения всех отправленных запросов. Этот экземпляр будет использоваться для возврата последнего выполненного запроса и используется в индикаторе для возврата последнего вставленного элемента.
Обратите внимание, что в каждой мере мы устанавливаем класс, который будет использоваться как папка в jconsole . Кроме того, предусмотрена метка для использования в качестве имени внутри папки.
Давайте посмотрим на скриншот jconsole с предыдущей конфигурацией и выполнением трех поисков:
По умолчанию все метрики видны через JMX . Но, конечно, мы можем сообщить об измерениях на консоль , http-сервер , Ganglia или Graphite .
Также обратите внимание, что в этом примере мы смешиваем код бизнес-кода и метрик. Если вы планируете использовать
Метрики в вашем производственном коде Я предлагаю вам по возможности помещать логику метрик в AOP.
Мы изучили простой способ мониторинга наших приложений без непосредственного использования JMX . Также имейте в виду, что Metrics поставляется с некоторыми встроенными метриками для инструментов HttpClient , JDBI , Jetty , Jersey , Log4j , Logback или веб-приложений .
Ссылка: Yammer Metrics, новый способ мониторинга вашего приложения от нашего партнера JCG Алекса Сото в блоге One Jar To Rule All .