比如一个系统后天服务,我们可能需要了解一些下面的一些情况:
1、每秒钟的请求是多少(TPS)?
2、平均每个请求处理的时间?
3、请求处理最长耗时?
4、等待处理的请求队列的长度?
Metrics的五中类型:
1.Gauges
一个比较简单的度量指标,用来统计瞬时状态,只是一个简单的返回值。例如我们想统计一个待处理队列中任务的个数
public static Queue<String> q = new LinkedList<String>()
MetricRegistry metricRegistry = new MetricRegistry(); ConsoleReporter reporter = ConsoleReporter.forRegistry(metricRegistry).build(); reporter.start(1, TimeUnit.SECONDS); metricRegistry.register(MetricRegistry.name(GaugeTest.class, "queue", "size"), new Gauge<Integer>(){ @Override public Integer getValue() { return q.size(); } });
2.Counter
Counter就是一个计数器,Counter只是用Guages封装了AtomicLong,维护了一个计数器,可以通过inc()和dec()方法对计数器进行修改
/** * 实例化一个registry,最核心的一个模块,相当于一个应用程序的metrics系统的容器,维护一个Map */ private static final MetricRegistry metrics = new MetricRegistry(); /** * 实例化一个counter,同样可以通过如下方式进行实例化再注册进去 * pendingJobs = new Counter(); * metrics.register(MetricRegistry.name(TestCounter.class, "pending-jobs"), pendingJobs); */ private static Counter pendingJobs = metrics.counter(name(TestCounter.class, "pedding-jobs")); /** * 在控制台上打印输出 */ private static ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build(); reporter.start(3, TimeUnit.SECONDS); while(true){ add("1"); Thread.sleep(1000); } public static void add(String str) { pendingJobs.inc(); queue.offer(str); }
3. Meters
Meters用来度量一系列事件发生的速率(rate),某个时间段内的平均处理次数(TPS),每1,5,15分钟和全部事件的的TPS。 比如一个service的请求数,通过mertic.meter()实例化一个meter之后,然后通过meter.mark()方法就能将本次的请求记录下来。统计结果有总的请求数,平均每秒的请求数,以及最近1,5,15分钟的平均TPS
MetricRegistry registry = new MetricRegistry(); ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build(); reporter.start(1, TimeUnit.SECONDS); Meter meterTps = registry.meter(MetricRegistry.name(MeterTest.class, "request", "tps")); while(true) { request(meterTps, random.nextInt(5)); Thread.sleep(1000); }
public static void request(Meter meter) { System.out.println("request"); meter.mark(); } public static void request(Meter meter, int n) { while(n > 0) { request(meter); n--; } }
4.Histograms 统计数据的百分情况。比如最小值,最大值,中位数,75百分位,90百分位,95百分位,98百分位,99百分位,99.9百分位的值
MetricRegistry registry = new MetricRegistry();
ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
reporter.start(1, TimeUnit.SECONDS);
Histogram histogram = new Histogram(new ExponentiallyDecayingReservoir());
registry.register(MetricRegistry.name(HistogramsTest.class, "request", "histogram"), histogram);
while (true)
{
Thread.sleep(1000);
histogram.update(random.nextInt(100000));
}
5.Timer
Timer其实是Histogram和Meter的结合,historram统计某部分代码/调用的耗时,meter统计TPS
MetricRegistry registry = new MetricRegistry();
ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
reporter.start(1, TimeUnit.SECONDS);
Timer timer = registry.timer(MetricRegistry.name(TimerTest.class, "get-latency"));
Timer.Context ctx;
while (true)
{
ctx = timer.time();
Thread.sleep(random.nextInt(1000));
ctx.stop();
}