Micrometer自定义业务监控指标


[原文链接] https://github.com/TFdream/blog/issues/340

SpringBoot 2.0 Micrometer 自定义业务指标监控

1、简介

Micrometer 为 Java 平台上的性能数据收集提供了一个通用的 API,它提供了多种度量指标类型(Timers、Guauges、Counters等),同时支持接入不同的监控系统,例如 Influxdb、Graphite、Prometheus 等。我们可以通过 Micrometer 收集 Java 性能数据,配合 Prometheus 监控系统实时获取数据,并最终在 Grafana 上展示出来,从而很容易实现应用的监控。

1.1 核心概念

Micrometer 中有两个最核心的概念,分别是计量器(Meter)和计量器注册表(MeterRegistry)。计量器用来收集不同类型的性能指标信息,Micrometer 提供了如下几种不同类型的计量器:

  • 计数器(Counter): 表示收集的数据是按照某个趋势(增加/减少)一直变化的,也是最常用的一种计量器,例如接口请求总数、请求错误总数、队列数量变化等。
  • 计量仪(Gauge): 表示搜集的瞬时的数据,可以任意变化的,例如常用的 CPU Load、Mem 使用量、Network 使用量、实时在线人数统计等,
  • 计时器(Timer): 用来记录事件的持续时间,这个用的比较少。
  • 分布概要(Distribution summary): 用来记录事件的分布情况,表示一段时间范围内对数据进行采样,可以用于统计网络请求平均延迟、请求延迟占比等。

1.2 MeterRegistry

Meter是收集关于你的应用的一系列指标的接口。Meter是由MeterRegistry创建的。每个支持的监控系统都必须实现MeterRegistry。Micrometer中包含一个SimpleMeterRegistry,它在内存中维护每个meter的最新值,并且不支持将数据导出到任何地方,主要用来进行本地开发和测试。
Micrometer 支持多个不同的监控系统。通过计量器注册表实现类 CompositeMeterRegistry 可以把多个计量器注册表组合起来,从而允许同时发布数据到多个监控系统。对于由这个类创建的计量器,它们所产生的数据会对 CompositeMeterRegistry中包含的所有计量器注册表都产生影响。

1.3 Actuator

你可以通过文末的参考文章获取它的详细概念和具体使用方法。这里只是简述下他的概念和使用方式,本文重点在micrometer。

Spring Boot Actuator是Spring Boot的一个组件,可以帮助你监控和管理Spring Boot应用,比如健康检查、审计、统计和HTTP追踪等。所有的这些特性可以通过JMX或者HTTP endpoints来获得。
你可以访问 http://ip:端口/actuator 查看系统中暴露的endpoint信息,也可以加上具体的 endpoint 查看他们的详细情况,例如 http://127.0.0.1:7001/actuator/health 查看健康信息。Spring Boot 2中的依赖actuator中集成的度量统计API使用的框架是Micrometer。官网

本文重点介绍/actuator/metrics,其他的就属于抛砖了。

1.4 metrics

打开 ip:端口/actuator/metrics 网址就可以看到当前微服务的所有metrics,每一个metric都相当于influx数据库的一个measurement,也就是传统数据库的数据表的概念。

2、自定义metrics

本篇以监控线程池中的待执行任务数量监控为例

首先,添加以下依赖:

<!-- 微服务运行监控  -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
    <version>${micrometer.version}</version>
</dependency>
<!-- 统计信息输出到 prometheus -->
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
    <version>${micrometer.version}</version>
</dependency>

2. 两种常用指标类型(Metric Type)

gauge: 可增可减计数器,反应某值当前一刻状态。比如称重传感器的当前重量,温度传感器的当前温度。
方式一:

Gauge.builder("lego.thread-pool.pending_task", new AtomicInteger(37), AtomicInteger::get)

方式二:

registry.gauge("lego.thread-pool.pending_task", Tags.of("site", "SiteA", "cab", "cab01"), new AtomicInteger(37));

两者等价

3. 接入到系统的方式

方式一,业务系统埋点:

@Component
public class SampleBean {
    private final Counter counter;

    public SampleBean(MeterRegistry registry) {
        this.counter = registry.counter("request.counter");
    }

    public void handleMessage(String message) {
        this.counter.increment();
        // handle message implementation
    }
}

方式二:MeterBinder

SpringBoot中提供了MeterBinder接口用于申明与注册meterRegistry。自定义Metrics只需要实现MeterBinder接口,Spring会自动发现并完成后续的杂活。

/**
 * @author Ricky Fung
 */
public class DynamicThreadPoolExecutorMetrics implements MeterBinder {
    private final Logger LOG = LoggerFactory.getLogger(this.getClass());

    @Autowired(required = false)
    private List<DynamicThreadPoolExecutor> executors = Collections.EMPTY_LIST;

    @Override
    public void bindTo(MeterRegistry meterRegistry) {
        String localIp = IpUtils.getLocalIp();
        LOG.info("动态线程池-监控自动装配开始, localIp:{}, meterRegistry:{}", localIp, meterRegistry.getClass());

        for (DynamicThreadPoolExecutor executor : executors) {
            String name = executor.getName();
            AtomicInteger pendingTask = new AtomicInteger(0);
            Gauge.builder("lego.thread-pool.pending_task", pendingTask, AtomicInteger::get)
                    .tag("name", name)
                    .tag("IP", localIp)
                    .description("动态线程池待执行任务数")
                    .register(meterRegistry);

            Counter totalTask = Counter.builder("lego.thread-pool.total_task")
                    .tag("name", name)
                    .tag("IP", localIp)
                    .description("动态线程池累计提交任务数")
                    .register(meterRegistry);

        }

    }
}

相关资料


文章作者: Kevin
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Kevin !
评论
  目录