在我们的平台开发到一定阶段之时,线上的机器越来越多,接口调用也越来越频繁,此时就需要一些监控,从服务器资源,以及业务指标监控.经过一些相关文档的查询最终选择了Metric度量类库来作为完成监控工作的工具。
在Maven中引入依赖
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>${metrics.version}</version>
</dependency>
可通过官网地址获取最新版本
1. Gauges(度量)
2. Counters(计数器)
3. Histograms(直方图数据)
4. Meters(TPS计算器)
5. Timers(计时器)
Metrics中MetricRegistry是中心容器,它是程序中所有度量的容器,所有新的度量工具都要注册到一个MetricRegistry实例中才可以使用,尽量在一个应用中保持让这个MetricRegistry实例保持单例。
通过@Bean注解配置指标容器
@Bean
public MetricRegistry metrics() {
return new MetricRegistry();
}
通过度量容器获得可以在调用的地方统计接口的请求数TPS,查询的次数QOS,并且根据时间来进行计算获取每秒的值。
public String method() {
Meter meter = registry.meter("you-meters-name");
meter.mark();
return "ok";
}
-- Meters ----------------------------------------------------------------------request
count = 21055
mean rate = 133.35 events/second
1-minute rate = 121.66 events/second
5-minute rate = 36.99 events/second
15-minute rate = 13.33 events/second
public String method() {
Counter counter = registry.counter("you-counter-name");
counter.inc();
return "ok";
}
-- Counters --------------------------------------------------------------------
requestCount
count = 21051
以上两种则是我在近期的工作中所使用到的两种度量工具,用于统计接口的TPS或者一些需要计数的场景.至于其他三种工具感兴趣的朋友可以自行测试用法与上面两种用法相同,通过容器的获取然后调用即可触发监控。
在Metrics类库中提供了四种原生将监控信息收集的方式分别是console,JMX,HTTP,Slf4j。
示例
@Bean
public ConsoleReporter consoleReporter(MetricRegistry metrics) {
return ConsoleReporter.forRegistry(metrics)
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.build();
}
以上几种不同的数据收集方式都是通过@Bean的形式将实例注入到容器之中,其根据设定好的时间自动运行.不便于我们进行数据的入库管理或计算。
我在实际应用中实现了数据收集接口,自定义了入库逻辑,将收集到的数据按照规定的频率进行入库,便于平台上进行展示,或于系统内部做相关业务应用。
public class DemoReport extends ScheduledReporter {
private static final Logger log = LoggerFactory.getLogger(DemoReport.class);
/**
* Called periodically by the polling thread. Subclasses should report all the given metrics.
*/
@Override
public void report(SortedMap<String, Gauge> gauges, SortedMap<String, Counter> counters, SortedMap<String, Histogram> histograms, SortedMap<String, Meter> meters, SortedMap<String, Timer> timers){
System.out.println("gauges = " + gauges);
System.out.println("counters = " + counters);
System.out.println("histograms = " + histograms);
System.out.println("meters = " + meters);
meters.entrySet().forEach(item -> {
String key = item.getKey();
System.out.println("key = " + key);
Meter value = item.getValue();
printMeter(value);
});
System.out.println("timers = " + timers);
}
}
启动监控
当以上前置操作完成之后,只需在启动类处获取对应的收集工具实例,调用其start方法便能够进行所需的指标监控。
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
ConsoleReporter bean = run.getBean(ConsoleReporter.class);
bean.start(5, TimeUnit.SECONDS);
}
注意项
1.将收集的开关放在启动类不便于项目的管理可以通过配置文件和@PostConstrust注解的搭配将开关放入到配置文件中,亦可以通过接口调用的方式实现开关。
2.在Metric类库中单一的工具是已经封装完成的单例,而MetricRegistry是中心容器,并且所有的工具都需要注册到容器中才能使用,所以也应该让其实例保持单例。
3.在多节点情况下各个节点之间并不互通,需人工的处理各个节点间数据的逻辑问题。