转载自:http://o-u-u.com/?p=1753
http://www.cnblogs.com/super-d2/p/5002061.html
Metrics是一个给JAVA服务的各项指标提供度量工具的包,在JAVA代码中嵌入Metrics代码,可以方便的对业务代码的各个指标进行监控。作为一款监控指标的度量类库,它提供了很多模块可以为第三方库或者应用提供辅助统计信息, 比如Jetty, Logback, Log4j, Apache HttpClient, Ehcache, JDBI, Jersey, 它还可以将度量数据发送给Ganglia和Graphite以提供图形化的监控。
Metrics提供了Gauge、Counter、Meter、Histogram、Timer等度量工具类以及Health Check功能。
Gauge (仪表)
Gauge代表一个度量的即时值,一般用来统计瞬时状态的数据信息。程序运行时的内存使用量和CPU占用率都可以通过Gauge值来度量。比如可以查看一个队列当前的size。
package org.zero.metrics;
import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
public class MetricsDemo {
//实例化一个MetricRegistry,最核心的一个模块,相当于一个应用程序的metrics系统的容器,维护一个Map
private static final MetricRegistry metrics = new MetricRegistry();
//在控制台上打印输出
private static ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build();
public static void main(String[] args) throws Exception {
gaugeTest();
}
static void gaugeTest() throws Exception {
reporter.start(3, TimeUnit.SECONDS); //每3秒report一次
Queue<String> queue = new LinkedBlockingDeque<>();
//实例化一个Gauge
Gauge<Integer> gauge = new Gauge<Integer>() {
@Override
public Integer getValue() {
return queue.size();
}
};
//注册到容器中
metrics.register(MetricRegistry.name(MetricsDemo.class, "queue", "size"), gauge);
for (int i = 0; i < 20; i++) {
queue.add("a");
Thread.sleep(1000);
}
}
}
registry中的每一个metric都有唯一的名字,可以通过MetricRegistry.name来生成,上述示例生成的name为org.zero.metrics.MetricsDemo.queue.size。运行结果:
17-4-09 21:30:06 ===============================================================
-- Gauges ----------------------------------------------------------------------
org.zero.metrics.MetricsDemo.queue.size
value = 4
17-4-09 21:30:09 ===============================================================
-- Gauges ----------------------------------------------------------------------
org.zero.metrics.MetricsDemo.queue.size
value = 6
17-4-09 21:30:12 ===============================================================
-- Gauges ----------------------------------------------------------------------
org.zero.metrics.MetricsDemo.queue.size
value = 9
17-4-09 21:30:15 ===============================================================
-- Gauges ----------------------------------------------------------------------
org.zero.metrics.MetricsDemo.queue.size
value = 12
17-4-09 21:30:18 ===============================================================
-- Gauges ----------------------------------------------------------------------
org.zero.metrics.MetricsDemo.queue.size
value = 15
17-4-09 21:30:21 ===============================================================
-- Gauges ----------------------------------------------------------------------
org.zero.metrics.MetricsDemo.queue.size
value = 18
另外,Core包种还扩展了几种特定的Gauge:
JMX Gauges—提供给第三方库只通过JMX将指标暴露出来。
Ratio Gauges—简单地通过创建一个gauge计算两个数的比值。
Cached Gauges—对某些计量指标提供缓存。
Counter (计数器)
Counter是Gauge的一个特例,维护一个计数器,可以通过inc()和dec()方法对计数器做修改。使用步骤与Gauge基本类似,在MetricRegistry中提供了静态方法可以直接实例化一个Counter。 static void counterTest() {
/**
* 实例化一个counter,同样可以通过如下方式进行实例化再注册进去
* Counter conunter = new Counter();
* metrics.register(MetricRegistry.name(MetricsDemo.class, "counter"), conunter);
**/
Counter conunter = metrics.counter(name(MetricsDemo.class, "counter"));
Queue<String> queue = new LinkedList<String>();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
conunter.inc();//在具体业务代码中对conunter修改
// conunter.dec();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
reporter.start(1, TimeUnit.SECONDS);
}
运行结果:
-- Counters --------------------------------------------------------------------
org.zero.metrics.MetricsDemo.counter
count = 5
Meter
Meters用来度量某个时间段的平均处理次数(request per second),每1、5、15分钟的TPS。比如一个service的请求数,通过metrics.meter()实例化一个Meter之后,然后通过meter.mark()方法就能将本次请求记录下来。统计结果有总的请求数,平均每秒的请求数,以及最近的1、5、15分钟的平均QPS。 static void metersTest() {
/** * 实例化一个Meter */
Meter requests = metrics.meter(MetricRegistry.name(MetricsDemo.class, "request"));
new Thread(() -> {
for (int i = 0; i < 2000; i++) {
try {
requests.mark();// handleRequest
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
reporter.start(3, TimeUnit.SECONDS);
}
运行结果:
-- Meters ----------------------------------------------------------------------
org.zero.metrics.MetricsDemo.request
count = 820
mean rate = 89.09 events/second
1-minute rate = 84.60 events/second
5-minute rate = 84.60 events/second
15-minute rate = 84.60 events/second
Histogram (直方图)
Histograms主要使用来统计数据的分布情况,最大值、最小值、平均值、中位数,百分比(75%、90%、95%、98%、99%和99.9%)。例如,需要统计某个页面的请求响应时间分布情况,可以使用该种类型的Metrics进行统计。具体的样例代码如下: static void histogramsTest() {
Histogram randomNums = metrics.histogram(MetricRegistry.name(MetricsDemo.class, "random"));
new Thread(() -> {
for (int i = 0; i < 2000; i++) {
try {
randomNums.update(i * 100);
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
reporter.start(3, TimeUnit.SECONDS);
}
运行结果:
-- Histograms ------------------------------------------------------------------
org.zero.metrics.MetricsDemo.random
count = 561
min = 0
max = 56000
mean = 28431.21
stddev = 16189.63
median = 28600.00
75% <= 42500.00
95% <= 53400.00
98% <= 55000.00
99% <= 55500.00
99.9% <= 56000.00
Timer (计时器)
Timers主要是用来统计某一块代码段的执行时间以及其分布情况,具体是基于Histograms和Meters来实现的。样例代码如下: static void timerTest(){
Timer requests = metrics.timer(MetricRegistry.name(MetricsDemo.class, "request"));
new Thread(() -> {
Random random = new Random();
for (int i = 0; i < 200; i++) {
Timer.Context context = requests.time();
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
context.stop();
}
}
}).start();
reporter.start(3, TimeUnit.SECONDS);
}
运行结果:
-- Timers ----------------------------------------------------------------------
org.zero.metrics.MetricsDemo.request
count = 13
mean rate = 2.11 calls/second
1-minute rate = 2.00 calls/second
5-minute rate = 2.00 calls/second
15-minute rate = 2.00 calls/second
min = 95.38 milliseconds
max = 791.00 milliseconds
mean = 446.68 milliseconds
stddev = 219.70 milliseconds
median = 481.22 milliseconds
75% <= 577.06 milliseconds
95% <= 791.00 milliseconds
98% <= 791.00 milliseconds
99% <= 791.00 milliseconds
99.9% <= 791.00 milliseconds
Health Check (健康检查)
Metric还提供了服务健康检查能力, 由metrics-healthchecks模块提供。
更多内容参考官网:http://metrics.dropwizard.io/,如果想将metrics的数据发送到influxdb或则其它地方,可以借鉴下github上metrics-influxdb的实现。