首页 > 其他分享 >Metrics 入门教程

Metrics 入门教程

时间:2023-01-02 22:33:08浏览次数:72  
标签:metrics 入门教程 MetricRegistry Metrics job static registry


Metrics,谷歌翻译就是度量的意思。当我们需要为某个系统某个服务做监控、做统计,就需要用到Metrics。

举个栗子,一个图片压缩服务:

  1. 每秒钟的请求数是多少(TPS)?
  2. 平均每个请求处理的时间?
  3. 请求处理的最长耗时?
  4. 等待处理的请求队列长度?

又或者一个缓存服务:

  1. 缓存的命中率?
  2. 平均查询缓存的时间?

基本上每一个服务、应用都需要做一个监控系统,这需要尽量以少量的代码,实现统计某类数据的功能。

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

本文就结合范例来主要介绍下 dropwizard/metrics 的概念和用法。

Maven 配置

我们需要在​​pom.xml​​​中依赖 ​​metrics-core​​ 包:

<dependencies>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>${metrics.version}</version>
</dependency>
</dependencies>

 

注:在POM文件中需要声明 ${metrics.version} 的具体版本号,如 3.1.0

Metric Registries

​MetricRegistry​​类是Metrics的核心,它是存放应用中所有metrics的容器。也是我们使用 Metrics 库的起点。

MetricRegistry registry = new

每一个 metric 都有它独一无二的名字,Metrics 中使用句点名字,如 com.example.Queue.size。当你在 com.example.Queue 下有两个 metric 实例,可以指定地更具体:com.example.Queue.requests.size 和 com.example.Queue.response.size 。使用​​MetricRegistry​​类,可以非常方便地生成名字。

MetricRegistry.name(Queue.class, "requests", "size")
MetricRegistry.name(Queue.class, "responses", "size")

Metrics 数据展示

Metircs 提供了 Report 接口,用于展示 metrics 获取到的统计数据。​​metrics-core​​​中主要实现了四种 reporter:​​JMX​​​, ​​console​​​, ​​SLF4J​​​, 和 ​​CSV​​。 在本文的例子中,我们使用 ConsoleReporter 。

五种 Metrics 类型

Gauges

最简单的度量指标,只有一个简单的返回值,例如,我们想衡量一个待处理队列中任务的个数,代码如下:

public class GaugeTest
public static Queue<String> q = new
public static void main(String[] args) throws{
MetricRegistry registry = new
ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
reporter.start(1, TimeUnit.SECONDS);
registry.register(MetricRegistry.name(GaugeTest.class, "queue", "size"),
new
public Integer getValue(){
return
}
});
while(true){
Thread.sleep(1000);
q.add("Job-xxx");
}
}
}

 

运行之后的结果如下:

-- Gauges ------------------------------------------------
com.alibaba.wuchong.metrics.GaugeTest.queue.size
value = 6

 

其中第7行和第8行添加了ConsoleReporter,可以每秒钟将度量指标打印在屏幕上,理解起来会更清楚。

但是对于大多数队列数据结构,我们并不想简单地返回​​queue.size()​​​,因为​​java.util​​​和​​java.util.concurrent​​​中实现的​​#size()​​方法很多都是 O(n) 的复杂度,这会影响 Gauge 的性能。

Counters

Counter 就是计数器,Counter 只是用 Gauge 封装了 ​​AtomicLong​​ 。我们可以使用如下的方法,使得获得队列大小更加高效。

public class CounterTest
public static Queue<String> q = new
public static
public static Random random = new
public static void addJob(String job){
pendingJobs.inc();
q.offer(job);
}
public static String takeJob(){
pendingJobs.dec();
return
}
public static void main(String[] args) throws{
MetricRegistry registry = new
ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
reporter.start(1, TimeUnit.SECONDS);
pendingJobs = registry.counter(MetricRegistry.name(Queue.class,"pending-jobs","size"));
int num = 1;
while(true){
Thread.sleep(200);
if (random.nextDouble() > 0.7){
String job = takeJob();
System.out.println("take job : "+job);
}else{
String job = "Job-"+num;
addJob(job);
System.out.println("add job : "+job);
}
num++;
}
}
}

运行之后的结果大致如下:

add job : Job-15
add job : Job-16
take job : Job-8
take job : Job-10
add job : Job-19
15-8-1 16:11:31
-- Counters ----------------------------------------------
java.util.Queue.pending-jobs.size
count = 5

 

Meters

Meter度量一系列事件发生的速率(rate),例如TPS。Meters会统计最近1分钟,5分钟,15分钟,还有全部时间的速率。

public class MeterTest
public static Random random = new
public static void request(Meter meter){
System.out.println("request");
meter.mark();
}
public static void request(Meter meter, int{
while(n > 0){
request(meter);
n--;
}
}
public static void main(String[] args) throws{
MetricRegistry registry = new
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);
}
}
}

运行结果大致如下:

request
15-8-1
-- Meters ------------------------------------------------
com.alibaba.wuchong.metrics.MeterTest.request.tps
count = 134
mean rate = 2.13 events/second
1-minute rate = 2.52 events/second
5-minute rate = 3.16 events/second
15-minute rate = 3.32 events/second

 

注:非常像 Unix 系统中 uptime 和 top 中的 load。

Histograms

Histogram统计数据的分布情况。比如最小值,最大值,中间值,还有中位数,75百分位, 90百分位, 95百分位, 98百分位, 99百分位, 和 99.9百分位的值(percentiles)。

比如request的大小的分布:

public class HistogramTest
public static Random random = new
public static void main(String[] args) throws{
MetricRegistry registry = new
ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
reporter.start(1, TimeUnit.SECONDS);
Histogram histogram = new Histogram(new
registry.register(MetricRegistry.name(HistogramTest.class, "request", "histogram"), histogram);
while(true){
Thread.sleep(1000);
histogram.update(random.nextInt(100000));
}
}
}

 

运行之后结果大致如下:

-- Histograms --------------------------------------------
java.util.Queue.queue.histogram
count = 56
min = 1122
max = 99650
mean = 48735.12
stddev = 28609.02
median = 49493.00
75% <= 72323.00
95% <= 90773.00
98% <= 94011.00
99% <= 99650.00
99.9% <= 99650.00

 

Timers

Timer其实是 Histogram 和 Meter 的结合, histogram 某部分代码/调用的耗时, meter统计TPS。

public class TimerTest
public static Random random = new
public static void main(String[] args) throws{
MetricRegistry registry = new
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();
}
}
}

运行之后结果如下:

-- Timers ------------------------------------------------
com.alibaba.wuchong.metrics.TimerTest.get-latency
count = 38
mean rate = 1.90
1-minute rate = 1.66
5-minute rate = 1.61
15-minute rate = 1.60
min = 13.90
max = 988.71
mean = 519.21
stddev = 286.23
median = 553.84
75% <= 763.64
95% <= 943.27
98% <= 988.71
99% <= 988.71
99.9% <= 988.71

 

其他

初次之外,Metrics还提供了 ​​HealthCheck​​​ 用来检测某个某个系统是否健康,例如数据库连接是否正常。还有​​Metrics Annotation​​,可以很方便地实现统计某个方法,某个值的数据。感兴趣的可以点进链接看看。

使用经验总结

一般情况下,当我们需要统计某个函数被调用的频率(TPS),会使用Meters。当我们需要统计某个函数的执行耗时时,会使用Histograms。当我们既要统计TPS又要统计耗时时,我们会使用Timers。

参考资料

本文代码已上传至​​GitHub​​。

 

 

标签:metrics,入门教程,MetricRegistry,Metrics,job,static,registry
From: https://blog.51cto.com/u_15861563/5984248

相关文章

  • HPA&&metrics-server
    27.HPA27.1Pod伸缩简介根据当前pod的负载,动态调整pod副本数量,业务高峰期自动扩容pod的副本数以尽快响应pod的请求在业务低峰期对pod进行缩容,实现降本增效的目的公有......
  • Linux 监控和调试利器 Sysdig 入门教程
    Sysdig简介Sysdig官网上对自己的介绍是:OpenSourceUniversalSystemVisibilityWithNativeContaierSupport.它的定位是系统监控、分析和排障的工具,其实在Linux......
  • 用户登录界面(Bootstrap)入门教程01(适合初学者)
    首先博主也是小白,之前没学过前端,花了一晚上做了个登录界面,想分享给大家,比较适合初学者来快速学习,博主以后也好好学基础的前端。首先先上我做的登录界面的图:因为博主水平有限......
  • sqoop入门教程
    目录一、Sqoop概述    1、简介    2、Sqoop架构原理    3、Sqoop连接器二、Sqoop安装    1、sqoop下载解压    2、sqoop配置文件 ......
  • Android基础入门教程
    一、Android介绍Android是一种基于Linux的自由及开放源代码的操作系统,Android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层。Andr......
  • ant使用指南详细入门教程
    一、概述ant是一个将软件编译、测试、部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发。在实际软件开发中,有很多地方可以用到ant。开发环境:复制代......
  • C#的λ表达式树(LambdaExpression)保姆级超详细简单入门教程
    有看过我之前发表过的C#相关文章分享和阅读过我代码的朋友们可能会在我的代码里面经常看到各种各样的λ表达式动态拼接,C#的λ表达式树是一个好东西,也是别的语言学不来......
  • FirewallD 基本知识(FirewallD入门教程)
    centos7中防火墙FirewallD是一个非常的强大的功能了,FirewallD提供了支持网络/防火墙区域(zone)定义网络链接以及接口安全等级的动态防火墙管理工具。它支持IPv4,IPv6......
  • Android基础入门教程
    一、Android介绍Android是一种基于Linux的自由及开放源代码的操作系统,Android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层。Andr......
  • ECMAScript 6 入门教程—Symbol
    作者|阮一峰1、概述ES5的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin模式),新方法的名字就有可能与......