Metrics,谷歌翻译就是度量的意思。当我们需要为某个系统某个服务做监控、做统计,就需要用到Metrics。基本上每一个服务、应用都需要做一个监控系统,这需要尽量以少量的代码,实现统计某类数据的功能。

例如对于图片压缩服务来说

  • 每秒钟的请求数是多少?
  • 平均每个请求处理的时间?
  • 请求处理的最长耗时?
  • 等待处理的请求队列长度?

例如对于缓存服务来说

  • 缓存的命中率?
  • 平均查询缓存的时间?

五种常用的Metrics类型

以 Java 为例,目前最为流行的 metrics 库是来自 Coda Hale 的 dropwizard/metrics,该库被广泛地应用于各个知名的开源项目中。例如 Hadoop,Kafka,Spark,JStorm 中。

Meter

Meter可以mark事件发生的次数,并且通过getCount方法返回事件发生的次数。Meter对象提供四种速率,分别是表示最近一分钟、最近五分钟、最近一个季度和整个Meter生命周期的平均速率。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Meter meter = new Meter();
long initCount = meter.getCount();
assertThat (initCount, equalTo(0L));

meter.mark();
assertThat (meter.getCount(), equalTo(1L));

meter.mark(20);
assertThat (meter.getCount(), equalTo(21L));

double meanRate = meter.getMeanRate();
double oneMinate = meter.getOneMinuteRate();
double fiveMinate = meter.getFiveMinuteRate();
double fifteenMinRate = meter.getFifteenMinuteRate();

Gauge

仅仅用于返回一个特定的值,metrics-core提供了几种实现

  • RatioGauge测量一个值和另一个值,他们两者之间的比率
  • CachedGauge设置值的过期时间
1
2
RatioGauge ratioGauge = new AttendanceRatioGauge(15, 20);
assertThat (ratioGauge.getValue(), equalTo(0.75));

Counter

用于去测量记录增加和减小。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Counter counter = new Counter();
long initCount = counter.getCount();
assertThat(initCount, equalTo (0L));

counter.inc();
assertThat(counter.getCount() , equalTo(1L));

counter.inc(11);
assertThat(counter.getCount(), equalTo(12L));

counter.dec();
assertThat(counter.getCount(), equalTo(11L));

counter.dec(6);
assertThat(counter.getCount(), equalTo(5L));

Histogram

用于跟踪值,并分析起统计特征,列入最大值、最小值、平均值、中值、标准差、第75百分位数等。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
Histogram histogram = new Histogram(new UniformReservoir());
histogram.update(5);
long count1 = histogram.getCount();
assertThat(count1, equalTo(1L));

Snapshot snapshot = histogram.getSnapshot() ;
assertThat(snapshot1.getValues().length, equalTo(1));
assertThat(snapshoti.getValues()[0], equalTo (5L));

histogram.update(20);
long count2 = histogram.getCount();
assertThat(count2, equalTo(2L));

Snapshot snapshot = histogram.getSnapshot();
assertThat (snapshot2.getValues().length, equalTo(2)); 
assertThat (snapshot2.getValues() [1], equalTo(20L));
assertThat(snapshot2.getMax(), equalTo(20L));
assertThat(snapshot2.getMean(), equalTo(12.5));
assertEquals(10.6, snapshot.getStdDev() , 0.1); 
assertThat(snapshot2.get75thPercentile(), equalTo(20.0)); 
assertThat(snapshot2.get999thPercentile(), equalTo(20.0));

Timer

用于跟踪由上下文对象表示的多个计时持续时间,并提供其统计数据。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Timer timer = new Timer();
Timer.Context context1 = timer.time();
TimeUnit.SECONDS.sleep(5);
long elapsed1 = context1.stop();

assertEquals (5000000000L, elapsed1, 1000000); 
assertThat (timergetCount (), equalTo (1L)); 
assertEquals (0.2, timer.getMeanRate (), 0.1);

Timer.Context context2 = timer.time ();
TimeUnit.SECONDS.sleep (2);
context2.close ();

assertThat (timer.getCount (), equalTo (2L)); 
assertEquals (0.3, timer getMeanRate(), 0.1);