云原生监控系统Prometheus——Sprint Boot可视化监控
Sprint Boot可视化监控
++
集成Spring Boot的Prometheus三剑客:Micrometer + Prometheus + Grafana
一、用Micrometer仪表化JVM应用
Micrometer(千分尺)是 Pivotal 为最流行的监控系统提供的一个简单的仪表客户端门面模式,允许仪表化 JVM 应用,而无须关心是哪个供应商提供的指标。
官网:https://micrometer.io/
As an instrumentation facade, Micrometer allows you to instrument your code with dimensional metrics with a vendor-neutral interface and decide on the monitoring system as a last step. Instrumenting your core library code with Micrometer allows the libraries to be included in applications that ship metrics to different backends.
Contains built-in support for AppOptics, Azure Monitor, Netflix Atlas, CloudWatch, Datadog, Dynatrace, Elastic, Ganglia, Graphite, Humio, Influx/Telegraf, JMX, KairosDB, New Relic, Prometheus, SignalFx, Google Stackdriver, StatsD, and Wavefront.
Spring Boot 2.x 在 spring-boot-actuator 中引入了 Micrometer。Spring Boot 2.x 对 Spring Boot 1.x 的指标进行了重构,从 https://micrometer.io 官网可以看到,Micrometer 也支持对接其他监控系统。Micrometer 和 Spring Boot、Prometheus 的桥接关系如下图:
通过门面模式接入 Micrometer 的监控系统,工整并且规范。用 Maven 依赖示例来说,其都是 micrometer-registry-XXX 类型的。
比如,接入 JMX 的依赖示例如下(https://micrometer.io/docs/registry/jmx):
In Gradle: compile 'io.micrometer:micrometer-registry-jmx:latest.release' Or in Maven: <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-jmx</artifactId> <version>${micrometer.version}</version> </dependency>
Micrometer 还包括开箱即用的缓存、类加载器、垃圾收集、处理器利用率、线程池以及更多针对可操作洞察的解决方案。
Micrometer 中最重要的两个概念是 Meters 和 Registry:
- Meters
Micrometer packs with a supported set of Meter primitives including: Timer, Counter, Gauge, DistributionSummary, LongTaskTimer, FunctionCounter, FunctionTimer, and TimeGauge. Different meter types result in a different number of time series metrics. For example, while there is a single metric that represents a Gauge, a Timer measures both the count of timed events and the total time of all events timed.
A meter is uniquely identified by its name and dimensions. We use the term dimensions and tags interchangeably, and the Micrometer interface is Tag simply because it is shorter. As a general rule it should be possible to use the name as a pivot. Dimensions allow a particular named metric to be sliced to drill down and reason about the data. This means that if just the name is selected, the user can drill down using other dimensions and reason about the value being shown.
- Registry
A Meter
is the interface for collecting a set of measurements (which we individually call metrics) about your application. Meters in Micrometer are created from and held in a MeterRegistry
. Each supported monitoring system has an implementation of MeterRegistry
. How a registry is created varies for each implementation.
Micrometer packs with a SimpleMeterRegistry
that holds the latest value of each meter in memory and doesn’t export the data anywhere. If you don’t yet have a preferred monitoring system, you can get started playing with metrics by using the simple registry:
MeterRegistry registry = new SimpleMeterRegistry();
在 Spring Boot 2.x 以后,Spring Boot Actuator 中用自带的 Micrometer 来实现监控。下面我们来看看 Spring Boot 中如何集成 Prometheus。
二、在Spring Boot 2.x中集成Prometheus的方法
Spring Boot 2.x 的 acutator 已经默认提供了 prometheus 调用的接口,但是需要依赖 micrometer-registry-prometheus(原文见Spring官网:https://docs.spring.io/spring-boot/docs/2.5.0/reference/htmlsingle/#legal 6.2.Endpoints),集成 Prometheus 可以分为如下4个步骤:
-
- 引入 Maven 依赖。
- application.properties 配置。
- 通过 MeterBinder 接口实现 bind 方法并注册到 MeterRegistry。(6.6.4. Registering Custom Metrics)
- 指标埋点。
2.1 引入 Maven 依赖
因为 Spring Boot 2.x 在 Actuator 模块中使用 Micrometer 来实现监控,所以要引入 spring-boot-starter-actuator 依赖(原文见Spring官网:https://docs.spring.io/spring-boot/docs/2.5.0/reference/htmlsingle/#legal 6.Spring Boot Actuator: Production-ready Features)。必要的 3 个配置分别是 spring-boot-starter-actuator、micrometer-registry-prometheus 和 micrometer-core。Maven 项目中 pom 文件的配置方式如下所示:
<!-- 监控系统健康情况的工具 https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>2.5.2</version> </dependency> <!-- 桥接 Prometheus https://mvnrepository.com/artifact/io.micrometer/micrometer-registry-prometheus --> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> <version>1.7.1</version> </dependency> <!-- micrometer 核心包,按需引入,使用 Meter 注解或手动埋点时需要 https://mvnrepository.com/artifact/io.micrometer/micrometer-core --> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-core</artifactId> <version>1.7.1</version> </dependency>
推荐加入 micrometer-jvm-extras 依赖,它可以获取 Spring Boot 的 JVM 信息,这些指标可以方便用户基于 Grafana 绘制可视化的 JVM 监控大屏。
<!-- 获取 jvm 相关信息,并展示在 Grafana上 https://mvnrepository.com/artifact/io.github.mweirauch/micrometer-jvm-extras --> <dependency> <groupId>io.github.mweirauch</groupId> <artifactId>micrometer-jvm-extras</artifactId> <version>0.2.2</version> </dependency>
2.2 application.properties 配置暴露采集点信息
对于 Spring Boot 2.x 而言,如果需要集成 Prometheus,那么 application.properties 的建议配置如下(参考Spring官网Appendix A: Common Application Properties:https://docs.spring.io/spring-boot/docs/2.5.0/reference/htmlsingle/#application-properties):
# spring.application.name属性必须有,一般为自己项目名称 spring.application.name=spring-boot-prometheus-demo management.metrics.tags.application=${spring.application.name} #Endpoint IDs that should be included or '*' for all. management.endpoints.web.exposure.include=* #Endpoint IDs that should be excluded or '*' for all. management.endpoints.web.exposure.exclude=prometheus,metrics #Whether to enable the shutdown endpoint. management.endpoint.shutdown.enabled=true #Whether, in the absence of any other exporter, exporting of metrics to an in-memory backend is enabled. management.metrics.export.simple.enabled=fals #Whether to enable the prometheus endpoint. management.endpoint.prometheus.enabled=true #Whether exporting of metrics to Prometheus is enabled. management.metrics.export.prometheus.enabled=true
可以通过如下命令远程关闭 Spring Boot 微服务:
curl -X POST localhost:8080/actuator/shutdown
2.3 自定义 metrics 类,实现 MeterBinder 接口采集和注册指标
通过 io.micrometer.core.instrument.binder.meterbinder 接口实现 bind 方法,并将要采集的指标注册到 MeterRegistry。
在这个案例中,我们通过注解的形式创建了一个 Spring Boot 中的 Component 组件 DemoMetrics,这个组件内置了一个计数器,用于对有计数需求的业务场景进行工具封装。
该组件内部代码的示例如下所示:
package com.example.demo.metrics; import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.counter; import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.binder.MeterBinder; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @Component public class YarnMetrics implements MeterBinder { public Counter counter; public Map<String,Double> map //Map 对象,用于对该组件进行扩展 //demoMetrics.map.put("x", counter1) //demoMetrics.map.put("y", counter2) //demoMetrics.map.put("z", counter3) //DemoMetrics 根据 Map 的 Key 的名称 x/y/z 取出业务端埋点值 DemoMeterics() { map = new HashMap<>(); @Override public void bindTo(MeterRegistry registry) { //定义并注册一个名称为 prometheus.demo.counter 的计数器,标签是 name:counter1 this.counter = Counter.builder("prometheus.demo.counter").tags(new String[]{"name","counter1"}).description("demo counter").register(meterRegistry); //从业务端传递的 Map 中取出与 Key 对应的值放入注册的 Gauge 仪表中,标签是 name:gauge1 Gauge.builder("prometheus.demo.gauge",map, x->x.get("x")).register(meterRegistry); } }
Counter 是一个只增不减的计数器,可以用来记录请求或者错误的总量,比如 http_requests_total 等。
Gauge 属于可增可减的仪表盘,更多用来反映应用当前的状态,比如主机当前空闲的内存 node_memory_MemFree 或者其他属性。
以上指标在上述代码中都进行了定义以及设置了标签。标签组合可以更好地表示应用及应用中的监控项,特别是在集群中。
2.4 以埋点的方式更新指标数据
注册完指标后就需要更新指标信息了。这里先略。
三、Spring Boot 2.x采集并可视化相关数据
Spring Boot 2.x 通过 Micrometer 提供了监控数据,但是这些数据并没有可视化,所以不够友好。如果要可视化,还需要我们执行两个操作:
-
- Prometheus 配置轮询采集 Spring Boot 2.x 的应用 target 提供的数据。
- Grafana 将 Prometheus 作为数据源可视化大盘展示。
第一项操作可以在 Prometheus 里的 prometheus.yml 文件中加上 Spring Boot 2.x 应用 8080 端口的 Job 采集,并重新加载配置文件即可,这样就可以将 Spring Boot 2.x的数据采集到 Prometheus 中。
scrape_configs: - job_name: 'prometheus' # Prometheus 自身配置 static_configs: - targets: ['localhost: 9090'] - job_name: 'springboot-demo' # Spring Boot 2.x 应用数据采集 metrics_path: '/actuator/prometheus' static_configs: - targets: ['localhost: 8080']
如上配置所示,http://localhost:8080/actuator/prometheus 页面中 Spring Boot 2.x 所应用的数据会被采集到 Prometheus 中。