内容简介:metrics-core为metrics核心库,定义了各种指标项,需要在pom.xml引用。MetricRegistry类是核心容器,内部使用ConcurrentHashMap维护所有监控指标项。 指标注册核心代码:
Metrics 作为一款监控指标的度量类库,提供了很多模块可以为第三方库或者应用提供辅助统计信息。Metrics内部提供了Gauge、Counter、Meter、Histogram、Timer等度量 工具 类以及Health Check功能。
Maven配置
metrics-core为metrics核心库,定义了各种指标项,需要在pom.xml引用。
<dependencies> <dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-core</artifactId> <version>3.1.0</version> </dependency> </dependencies> 复制代码
MetricRegistry
MetricRegistry类是核心容器,内部使用ConcurrentHashMap维护所有监控指标项。 指标注册核心代码:
public <T extends Metric> T register(String name, T metric) throws IllegalArgumentException { if (metric instanceof MetricSet) { registerAll(name, (MetricSet) metric); } else { final Metric existing = metrics.putIfAbsent(name, metric); if (existing == null) { onMetricAdded(name, metric); } else { throw new IllegalArgumentException("A metric named " + name + " already exists"); } } return metric; } 复制代码
每个指标项都需要有个独一无二的名字,MetricRegistry类提供了名字生成的方式。除了可以根据类名来生成名字外,也支持自定义名字。其本质是字符串的拼接。
public static String name(String name, String... names) { final StringBuilder builder = new StringBuilder(); append(builder, name); if (names != null) { for (String s : names) { append(builder, s); } } return builder.toString(); } public static String name(Class<?> klass, String... names) { return name(klass.getName(), names); } private static void append(StringBuilder builder, String part) { if (part != null && !part.isEmpty()) { if (builder.length() > 0) { builder.append('.'); } builder.append(part); } } 复制代码
Metrics数据展示
Metrics提供了Reporter接口,用于展示内部的数据指标信息。metrics-core中主要实现了ConsoleReporter、CsvReporter 、Slf4jReporter、JmxReporter。在本文例子中使用ConsoleReporter展示内部指标。
对于使用 Falcon 监控系统的公司,可以参照ConsoleReporter实现自定义的Reporter,这样Metrics就可以无缝集成到公司的监控系统上。
Metrics度量指标
Gauge
Gauge主要记录指标的瞬时值,如服务当前 Jvm 使用情况等;
public class JvmGaugeTest { public static void main(String[] args) throws Exception { MetricRegistry registry = new MetricRegistry(); ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build(); reporter.start(1, TimeUnit.SECONDS); MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean(); registry.register("jvm.total.used", new Gauge<Long>() { @Override public Long getValue() { return memoryMXBean.getHeapMemoryUsage().getUsed() + memoryMXBean.getNonHeapMemoryUsage().getUsed(); } }); while (true) { Thread.sleep(1000); } } } 复制代码
代码运行结果如下:
-- Gauges ---------------------------------------------------------------------- jvm.total.used value = 16314496 复制代码
Counter
Counter是计数器,可以对Counter进行增加和减少操作,维护累计的指标。
public class CounterTest { private static Queue<String> queue = new LinkedBlockingQueue<String>(); private static Counter pendingJobs; private static Random random = new Random(); public static void addJob(String job) { pendingJobs.inc(); queue.offer(job); } public static String takeJob() { pendingJobs.dec(); return queue.poll(); } public static void main(String[] args) throws InterruptedException { MetricRegistry registry = new MetricRegistry(); ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build(); reporter.start(1, TimeUnit.SECONDS); pendingJobs = registry.counter("pending.jobs.size"); for (int num = 1; ; num++) { Thread.sleep(100); if (random.nextDouble() > 0.8) { takeJob(); } else { addJob("Job-" + num); } } } } 复制代码
代码运行结果如下:
-- Counters -------------------------------------------------------------------- pending.jobs.size count = 19 复制代码
Meter
Meter度量事件发生的频率,统计最近1分钟、5分钟、15分钟的速率。
public class MeterTest { private static Random random = new Random(); public static void request(Meter meter, int times) { for (int i = 0; i < times; i++) { meter.mark(); } } public static void main(String[] args) throws InterruptedException { MetricRegistry registry = new MetricRegistry(); ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build(); reporter.start(1, TimeUnit.SECONDS); Meter meterTps = registry.meter("request.tps"); while (true) { request(meterTps, random.nextInt(10)); Thread.sleep(1000); } } } 复制代码
代码运行结果如下:
-- Meters ---------------------------------------------------------------------- request.tps count = 115 mean rate = 5.00 events/second 1-minute rate = 7.04 events/second 5-minute rate = 7.63 events/second 15-minute rate = 7.74 events/second 复制代码
Meter参考UNIX系统关于平均负荷load average来设计的,其中使用到了EMA 指数移动平均算法。越近期的数据加权影响力越重。
Histogram
Histogram统计数据分布情况,统计最小值、最大值、平均值、中位数、75分位、90分位、95分位、99分位、99.9分位等数据。
public class HistogramTest { private static Random random = new Random(); public static void main(String[] args) throws Exception { MetricRegistry registry = new MetricRegistry(); ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build(); reporter.start(1, TimeUnit.SECONDS); Histogram histogram = new Histogram(new UniformReservoir()); registry.register("request.histogram", histogram); while (true) { Thread.sleep(1000); histogram.update(random.nextInt(100)); } } } 复制代码
代码运行结果如下:
-- Histograms ------------------------------------------------------------------ request.histogram count = 18 min = 10 max = 98 mean = 53.28 stddev = 29.48 median = 44.50 75% <= 83.50 95% <= 98.00 98% <= 98.00 99% <= 98.00 99.9% <= 98.00 复制代码
数据抽样
Histogram需要统计数据分布,其内部必须抽样维护数据信息。内置的数据抽样有以下几种实现:
- ExponentiallyDecayingReservoir:基于指数级别的抽样算法,根据更新时间与开始时间的差值转化为权重值,权重越大数据被保留的几率越大。
- UniformReservoir:随机抽样,随着更新次数的增加,数据被抽样的概率会减少。
- SlidingWindowReservoir:滑动窗口抽样,总是保留最新的统计数据。
- SlidingTimeWindowReservoir:滑动时间窗口抽样,总是保留最近时间段的统计数据。
注意事项
若使用ExponentiallyDecayingReservoir和SlidingTimeWindowReservoir,需要注意容量,底层并不会限制容量大小。若服务流量大,可能会占用很多内存。
Timer
Timer是Histogram和Meter的结合,Histogram统计耗时分布,Meter统计QPS;
public class TimerTest { public static Random random = new Random(); private static void request() throws InterruptedException { Thread.sleep(random.nextInt(1000)); } public static void main(String[] args) throws Exception { MetricRegistry registry = new MetricRegistry(); ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build(); reporter.start(1, TimeUnit.SECONDS); Timer timer = registry.timer("request.latency"); Timer.Context ctx; while (true) { ctx = timer.time(); request(); ctx.stop(); } } } 复制代码
代码运行结果如下:
-- Timers ---------------------------------------------------------------------- request.latency count = 22 mean rate = 2.00 calls/second 1-minute rate = 1.98 calls/second 5-minute rate = 2.00 calls/second 15-minute rate = 2.00 calls/second min = 148.93 milliseconds max = 865.65 milliseconds mean = 491.89 milliseconds stddev = 219.59 milliseconds median = 465.60 milliseconds 75% <= 671.65 milliseconds 95% <= 850.28 milliseconds 98% <= 865.65 milliseconds 99% <= 865.65 milliseconds 99.9% <= 865.65 milliseconds 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
了不起的Node.js
劳奇 (Guillermo Rauch) / 赵静 / 电子工业出版社 / 2014-1 / 79.00元
本书是一本经典的 Learning by Doing的书籍。它由 Node社区著名的 Socket.IO作者—— Guillermo Rauch,通过大量的实践案例撰写,并由 Node社区非常活跃的开发者—— Goddy Zhao翻译而成。 本书内容主要由对五大部分的介绍组成: Node核心设计理念、 Node核心模块 API、Web开发、数据库以及测试。从前到后、由表及里地对使用 Node......一起来看看 《了不起的Node.js》 这本书的介绍吧!