一、前言
前几天因为需要,折腾了一下 Java Metrics。发现之前的文章中并没有写过这个。
本着要把所有看到的性能相关的话题都要涉及的目的,在这里也要写一下。
二、简介
Metrics的官网首页简单的很,里面只有这么段描述:
Metrics is a Java library which gives you unparalleled insight into what your code does in production.
Metrics provides a powerful toolkit of ways to measure the behavior of critical components in your production environment.With modules for common libraries like Jetty, Logback, Log4j, Apache HttpClient, Ehcache, JDBI, Jersey and reporting backends like Graphite, Metrics provides you with full-stack visibility.
也就是说这个工具包可以让你在生产环境中产生度量的一些数据,并且支持不同的输出方式。
它可以度量代码中关键组件,响应时间、计数器等都可以采集,也可以取操作系统信息。
它的基本类型有如下几种:
看下官网的文档结构,就知道它能干多少事了,英文不错的,可以看下 https://metrics.dropwizard.io/4.0.0/。
三、举例说明
来看一个 Meter 的例子:
/**
* Meter
* 作用:度量速率(例如,tps)
* Meters会统计最近1分钟(m1),5分钟(m5),15分钟(m15),还有全部时间的速率(速率就是平均值)。
*/
public class TestMeter {
public static void main(String[] args) throws InterruptedException {
/**
* 实例化一个MetricRegistry,是一个metrics的容器,维护一个MAP
*/
final MetricRegistry registry = new MetricRegistry(); //因为该类的一个属性final ConcurrentMap<String, Metric> metrics,在实际使用中做成单例就好
/**
* 实例化ConsoleReporter,输出
*/
ConsoleReporter reporter = ConsoleReporter.forRegistry(registry)
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.build();
reporter.start(3, TimeUnit.SECONDS); //从启动后的3s后开始(所以通常第一个计数都是不准的,从第二个开始会越来越准),每隔3秒从MetricRegistry钟poll一次数据
//实例化一个Meter并注册到容器中去
Meter meterTps = registry.meter(MetricRegistry.name(TestMeter.class, "request", "tps")); //将该Meter类型的指定name的metric加入到MetricsRegistry中去
System.out.println("执行与业务逻辑");
//模拟数据
while (true) {
meterTps.mark(); //总数以及m1,m5,m15的数据都+1
Thread.sleep(500);
}
}
}
上面完整的示例代码都有注释,就不一一解释了。输出如下:
-- Meters ----------------------------------------------------------------------
com.zee.metrics.zeemetrics.TestMeter.request.tps
count = 12
mean rate = 2.00 events/second
1-minute rate = 2.00 events/second
5-minute rate = 2.00 events/second
15-minute rate = 2.00 events/second
这就可以统计这个请求在这段时间内访问了多少次,也就是 TPS。但是也不能老在 console 里看呀。
还是放到图形化的界面中看比较好,这里用的是 influxDB+Grafana,在 influxDB 中创建一个 database。
[gaolou@7dgroup2 ~]$ influx
Connected to http://localhost:8086 version 1.6.0
InfluxDB shell version: 1.6.0
> create database mydb;
> use mydb;
Using database mydb
> show MEASUREMENTS
>
其中的 MEASUREMENTS 是空的。
把数据输出进去。
@Bean
public Meter requestMeter(MetricRegistry metrics) {
return metrics.meter("request");
}
@Bean(name = "influxdbReporter")
public ScheduledReporter influxdbReporter(MetricRegistry metrics) throws Exception {
return InfluxdbReporter.forRegistry(metrics)
.protocol(InfluxdbProtocols.http("1.1.1.1", 8086, "admin", "admin", "mydb"))
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.filter(MetricFilter.ALL)
.skipIdleMetrics(false)
.build();
}
select * from request
就看到产生了如下内容。
再配置下 grafana 中的 data source
在 dashboard 中加下 panel,选择 influxdb 数据源,看到列表,选择想要看的数据表,再在 field 中选择想要看的列,保存。
然后在 dashboard 里就可以看到数据了。
四、总结
这个逻辑,在操作中并不困难。但是,从我自己的行业经验上来看。在研发时就让他们把要看到的数据做好监控的规划,最后运维时能如此清晰地展示出来,并最终对判断生产问题有用,这个过程的沟通成功会非常的高。
主要是看公司的组织结构是什么样,如果是全栈的结构会比较容易
如果是研发运维是分开的团队,并且相互配合的不好,会相当的痛苦。
在之前的项目中,有运维问我怎么才能监控到业务性能,我想了下那个公司的背景之后,沉吟良久说了声:难。
性能可做的东西并不少,前提是看格局有多大。