Java 程式碼執行洞察庫 Metrics
它是由yammer開發的,用於檢測jvm上後端服務的執行狀況。Metrics提供了一個強大的工具集,用於度量你的生產環境上關鍵元件的行為。
Metrics提供了一組通用的模組庫用於支援比如Guice,Jetty,Log4j,Apache HttpClient,EhCache,Logback,Spring等,也提供對比如Ganglia和Graphite等後端的報告。
專案官網:http://metrics.dropwizard.io/
Metrics 主要有五大基本元件
1:Counter
記錄執行次數
2:Gauge
獲取某個值
3:Meter
用來計算事件的速率
4:Histogram
可以為資料流提供統計資料。 除了最大值,最小值,平均值外,它還可以測量 中值(median),百分比比如XX%這樣的Quantile資料
5:Timer
用來測量一段程式碼被呼叫的速率和用時。等於Meter+Hitogram,既算TPS,也算執行時間。
下面是程式碼例子
首先加入依賴
<dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-core</artifactId> <version>3.1.2</version> </dependency>
com.codahale.metrics.MetricRegistry 是Metrics的核心,這裡先用一個常量儲存
package com.lala.core;
import com.codahale.metrics.MetricRegistry;
public class MetricConstant
{
public static MetricRegistry REGISTER = new MetricRegistry();
}
上面也是說到了Metrics支援很多輸出,jmx, log4j , jetty, httpclient等等。我這裡就直接輸出到控制檯
package com.lala.core; import java.util.concurrent.TimeUnit; import com.codahale.metrics.ConsoleReporter; /** * 控制檯列印輸出 */ public class MyConsoleReport { public static void startReport() { final ConsoleReporter reporter = ConsoleReporter.forRegistry(MetricConstant.REGISTER) .convertRatesTo(TimeUnit.SECONDS) .convertDurationsTo(TimeUnit.SECONDS) .build(); //一秒鐘執行一次 reporter.start(1, TimeUnit.SECONDS); } }
首先,來一個基本的公共類
package com.lala.core;
import java.util.concurrent.TimeUnit;
import com.codahale.metrics.MetricRegistry;
public class Base
{
protected static MetricRegistry metric = MetricConstant.REGISTER;
protected static void secondSleep(long value)
{
try
{
TimeUnit.SECONDS.sleep(value);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
protected static void milliSecondSleep(long value)
{
try
{
TimeUnit.MILLISECONDS.sleep(value);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
接下來,就演示這五大元件的基本用法
一:Counter
package com.lala.demo;
import java.util.Random;
import com.codahale.metrics.Counter;
import com.lala.core.Base;
import com.lala.core.MyConsoleReport;
/**
* 記錄執行次數
*/
public class CounterTest extends Base
{
final static Counter exec = metric.counter("com.pp.counter.invoke");
public static void main(String[] args)
{
MyConsoleReport.startReport();
new Thread(()->{
for(int i=1;i<=3;i++)
{
exec.inc();
milliSecondSleep(new Random().nextInt(500)*2);
}
}).start();
secondSleep(3);
}
}
輸出如下:
15-11-22
20:38:29 ==============================================================
-- Counters --------------------------------------------------------------------
com.pp.counter.invoke
count = 3
二:Gauge
package com.lala.demo;
import com.codahale.metrics.Gauge;
import com.lala.core.Base;
import com.lala.core.MyConsoleReport;
/**
* 獲取某個值
*/
public class GaugeTest extends Base
{
public static void main(String[] args)
{
MyConsoleReport.startReport();
metric.register("com.pp.gauge.freeMemory", new Gauge<Long>(){
public Long getValue() {
//這裡是獲取當前JVM可用記憶體
return Runtime.getRuntime().freeMemory();
}
});
secondSleep(2);
}
}
輸出如下:
15-11-22 20:39:44 ==============================================================
-- Gauges ----------------------------------------------------------------------
com.pp.gauge.freeMemory
value = 118203344
三:Meter
package com.lala.demo;
import java.util.Random;
import com.codahale.metrics.Meter;
import com.lala.core.Base;
import com.lala.core.MyConsoleReport;
/**
* Meter用來計算事件的速率
*/
public class MeterTest extends Base
{
static final Meter requests = metric.meter("com.pp.meter.invoke");
public static void main(String[] args)
{
MyConsoleReport.startReport();
new Thread(()->{
for(int i=1;i<=2;i++)
{
requests.mark();
milliSecondSleep(new Random().nextInt(500)*2);
}
}).start();
secondSleep(2);
}
}
輸出如下:
15-11-22 20:40:57 ==============================================================
-- Meters ----------------------------------------------------------------------
com.pp.meter.invoke
count = 2
mean rate = 0.97 events/second
1-minute rate = 0.00 events/second
5-minute rate = 0.00 events/second
15-minute rate = 0.00 events/second
四:Histogram
package com.lala.demo;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import com.codahale.metrics.Histogram;
import com.lala.core.Base;
import com.lala.core.MyConsoleReport;
/**
* Histogram可以為資料流提供統計資料。 除了最大值,最小值,平均值外,它還可以測量 中值(median),
* 百分比比如XX%這樣的Quantile資料
*/
public class HistogramTest extends Base
{
static final Histogram his = metric.histogram("com.pp.histogram.score");
static List<Integer> scores = Arrays.asList(60, 75, 80, 62, 90, 42, 33, 95, 61, 73);
public static void main(String[] args)
{
MyConsoleReport.startReport();
new Thread(()->{
scores.forEach( (score) -> {
his.update(score);
milliSecondSleep(new Random().nextInt(500)*2);
});
}).start();
secondSleep(10);
}
}
輸出如下:
15-11-22 20:42:14 ==============================================================
-- Histograms ------------------------------------------------------------------
com.pp.histogram.score
count = 10
min = 33
max = 95
mean = 67.11
stddev = 18.70
median = 73.00
75% <= 80.00
95% <= 95.00
98% <= 95.00
99% <= 95.00
99.9% <= 95.00
五:Timer
package com.lala.demo;
import com.codahale.metrics.Timer;
import com.lala.core.Base;
import com.lala.core.MyConsoleReport;
/**
* Timer用來測量一段程式碼被呼叫的速率和用時。
* 等於Meter+Hitogram,既算TPS,也算執行時間。
*/
public class TimerTest extends Base
{
static final Timer timer = metric.timer("com.pp.timer.invoke");
static void inovke(long time)
{
final Timer.Context context = timer.time();
try
{
secondSleep(time);
}finally
{
context.stop();
}
}
public static void main(String[] args)
{
MyConsoleReport.startReport();
inovke(1);
inovke(2);
inovke(2);
inovke(8);
secondSleep(1);
}
}
輸出如下:
15-11-22 20:43:34 ==============================================================
-- Timers ----------------------------------------------------------------------
com.pp.timer.invoke
count = 4
mean rate = 0.28 calls/second
1-minute rate = 0.38 calls/second
5-minute rate = 0.40 calls/second
15-minute rate = 0.40 calls/second
min = 1.01 seconds
max = 8.00 seconds
mean = 3.44 seconds
stddev = 2.86 seconds
median = 2.00 seconds
75% <= 8.00 seconds
95% <= 8.00 seconds
98% <= 8.00 seconds
99% <= 8.00 seconds
99.9% <= 8.00 seconds
注意:這裡的輸出,和上一個元件輸出有些類似,但是不一樣的
這裡統計的是執行時間,什麼最大執行時間,最小執行時間,平均執行時間等。上一個統計的是數字,什麼最大數字,最小數字,平均數字等
當然了,Metrics還可以用來做心跳檢測,這裡就不演示了。