自己为了记录最近查到的资料 先记录下来 没去验证 不对文章负责
为了能自定义监控业务指标我们需要对springboot进行自定义监控。所以在这里我们用的是Micrometer,SpringBoot 2.0开始全面更改为Micrometer,Micrometer与Spring属于同门,都是Pivotal旗下的产品。
Micrometer工具
Micrometer为最流行的监控系统提供了一个简单的仪表客户端外观,允许仪表化JVM应用,而无需关心是哪个供应商提供的指标。Micrometer提供一组核心抽象API。核心内容包含在micrometer-core包中,每种开箱提供都有对应的Jar包,直接引入即可使用。
介绍
Meter
Meter是收集关于你的应用的一系列指标的接口。Meter是由MeterRegistry创建的。每个支持的监控系统都必须实现MeterRegistry。Meter也是所有度量的抽象,Micrometer提供了一组原生Meter类型,包括timer(计时器), gauge(量规), counter(计数器), distribution summaries(分布式摘要), long task timers(长任务定时器)。Meter由name和dimension来唯一标识,在Micrometer中dimension又等价于tag。name是监控项的名称,tag可以作为监控的指标内容,比如name:接口请求量;tag:接口url。这样便于分组利于统计分类。
Registry
Registry是Meter的注册中心,由Registry创建Meter并统一管理Meter,每个监控系统都有对应的MeterRegistry实现。Micrometer默认提供了基于内存、便于测试的SimpleRegistry以及一个静态全局注册表(Metrics.globalRegistry)。全局注册表是一个组合注册表(CompositeMeterRegistry ),当需要对接多个监控系统时,可以使用组合注册表并向其中添加多个Registry。
Micrometer中包含一个SimpleMeterRegistry,它在内存中维护每个meter的最新值,并且不将数据导出到任何地方。如果你还没有一个首选的监测系统,你可以先用SimpleMeterRegistry:
MeterRegistry registry = new SimpleMeterRegistry();
SimpleMeterRegistry在Spring中是自动注入的
Meter Filter
每个注册表都可以配置Meter过滤器,在工作项目中引入不同的依赖或者配合不同的工具往往需要传递MeterRegistry或者直接使用全局静态Registry,为了方便开发者收集指定的数据,或者对注册的Meter进行转换修改,Micrometer提供了Meter过滤器用于编写规则拒绝、转换或配置注册的Meter。
简单使用
Counter
计数器,它允许你增加固定的数量,且数量必须为正数,也就是说它描述一个递增的值。
// 第一种方式
MeterRegistry registry = new SimpleMeterRegistry();
// meterRegistry.counter("监控项名称", "tag的key", "tag的value");
Counter counter = meterRegistry.counter("urlCounter", "url", "http://localhost:9999/test");
counter.increment();
第二种方式
Counter metricsCounter = Metrics.counter("urlCounter", "url", "http://localhost:9999/test");
metricsCounter.increment();
Gauge
gauge是获取当前值的句柄,可以理解为直接的数值指标,典型的例子是线程池的活跃线程数量、集合的大小等,当指标不是递增的而是一个上下浮动的值时,你应该采用Gauge,同时Gauge也翻译为仪表盘,典型如汽车的速度仪表,这样就非常好理解了。
// 直接创建
Set<Tag> tagList = new HashSet<>();
tagList.add(Tag.of("tag1", "tag1value"));
tagList.add(Tag.of("tag2", "tag2value"));
Metrics.gauge("keyname", tagList, num);
// 构造器创建
Gauge gauge = Gauge
.builder("orderNum", myObj, myObj::gaugeValue)
.tag("region", "test")
.register(registry);
// 直接创建
MeterRegistry registry = new SimpleMeterRegistry();
List<String> list = registry.gauge("listGauge", Collections.emptyList(), new ArrayList<>(), List::size); //监视非数值对象
List<String> list2 = registry.gaugeCollectionSize("listSize2", Tags.empty(), new ArrayList<>()); //监视集合大小
Map<String, Integer> map = registry.gaugeMapSize("mapGauge", Tags.empty(), new HashMap<>());
Timer
Timer稍微有点绕,Timer记录的是单个事件执行消耗的时间,用于测量事件发生的频率和效率,例如统计一个小时内某个接口有多少次请求以及每次请求响应时间的平均值时,就可以用到Timer。注意Timer在事件结束时记录数据,每条记录代表一个时间段,在统计时需要注意区间的取值。
// 构造器创建
Timer timer = Timer
.builder("my.timer")
.description("a description of what this timer does") // optional
.tags("region", "test") // optional
.register(registry);
// 直接从Registry创建
registry.timer("my.timer", "region", "test");
// record directly
timer.record(Duration.of(60L, ChronoUnit.SECONDS));
// record function
timer.record(() -> {
// some operation ...
});
// wrap function
timer.wrap(() -> yourFunction());
// use sample
Timer.Sample sample = Timer.start();
// do something
sample.stop(timer);