Micrometer 提供了对接各种监控系统(Prometheus ,Influx,jmx, …)的门面(Facade),可以基于 Micrometer 来设计应用的监控系统(模块)。
例如,对于 Prometheus 监控系统,可以添加以下依赖:
<dependency>
<groupId>io.micrometergroupId>
<artifactId>micrometer-registry-prometheusartifactId>
<version>${micrometer.version}version>
dependency>
Micrometer is not a distributed tracing system or an event logger. Adrian Cole’s talk on Observability 3 Ways does a great job of highlighting the differences between these different types of systems.
监控系统的三个主要特征:
特征 | 说明 | 系统 |
---|---|---|
Dimensionality | 指标是否支持添加 key/value tags; | |
Rate aggregation | ||
Publishing |
有几个重要的概念,需要区分和理解:Meter(测量仪),Measurement(测量值),Metric(指标)
测量仪,测量物,测量值,指标
有时候,这些概念在交叉着使用,甚至相互替代,但是具体的内涵还是要理清楚的。
Meter 可以用来采集一组指标,在 Micrometer 中,通过 MeterRegistry 来构建 Meter 对象,每一种监控系统都有对应的 MeterRegistry 实现,比如 Influxdb 有 InfluxMeterRegistry。如果没有特定的外部监控系统,可以使用 SimpleMeterRegistry,它会将指标信息保存在内存中。
Mircrometer 提供了一个全局注册器 Metrics.globalRegistry 和一系列的静态方法,用来创建各类 Meter。
有两种基本的使用方式,如下所示:
class MyComponent {
Counter featureCounter = Metrics.counter("feature", "region", "test"); (1)
void feature() {
featureCounter.increment(); // 方式1: 将 Counter 作为 MyComponent 类的字段,减少了查询的消耗
}
void feature2(String type) { // 方法2: 通过 Metrics 查询所需的 Counter 对象,然后调用 increment() 方法;
Metrics.counter("feature.2", "type", type).increment(); (2)
}
}
Micrometer 支持以下类型的指标:
短期
一般指小于一分钟。不同类型的 meter 生成的指标序列也不同,例如 Gauge 是个标量指标,对应一个 metric,而 Timer 类型的 meter 不仅涉及指标值,还保留了指标时间的信息。
一个 Meter 是由其名称和属性来共同标识,Meter 的属性有时候也称为纬度(dimensions),在 Micrometer 库中,使用 Tag 接口来定义属维度。维度除了用来标识 Meter,还可以用来对数据进行钻取操作。
Meter 的命名原则是小写名词以 .
相连,例如 http.server.requests
。不同的监控系统,也有自己的命名习惯,比如:
http_server_requests_duration_seconds
httpServerRequests
http.server.requests
http_server_requests
不同类型的 Registry,会将 Meter 风格的名称转换为其目标监控系统的风格。
spring-boot-metrics
在 pom.xml 文件中添加依赖包
org.springframework.boot
spring-boot-starter-actuator
io.micrometer
micrometer-registry-influx
1.5.1
然后,在配置文件中,对 influx registry 进行配置:
management.metrics.export.influx.uri=http://localhost:8086
management.metrics.export.influx.step=10s
management.metrics.export.influx.db=test_db
management.metrics.export.influx.enabled=true
参数的详细说明如下:
management.metrics.export.influx:
auto-create-db: true # Whether to create the Influx database if it does not exist before attempting to publish metrics to it. (Default: true)
batch-size: 10000 # Number of measurements per request to use for this backend. If more measurements are found, then multiple requests will be made. (Default: 10000)
compressed: true # Whether to enable GZIP compression of metrics batches published to Influx. (Default: true)
connect-timeout: 1s # Connection timeout for requests to this backend. (Default: 1s)
consistency: one # Write consistency for each point. (Default: one)
db: mydb # Tag that will be mapped to “host” when shipping metrics to Influx. (Defaut: mydb)
enabled: true # Whether exporting of metrics to this backend is enabled. (Default: true)
num-threads: 2 # Number of threads to use with the metrics publishing scheduler. (Default: 2)
password: mysecret # Login password of the Influx server.
read-timeout: 10s # Read timeout for requests to this backend. (Default: 10s)
retention-policy: my_rp # Retention policy to use (Influx writes to the DEFAULT retention policy if one is not specified).
step: 1m # Step size (i.e. reporting frequency) to use. (Default: 1m)
uri: http://localhost:8086 # URI of the Influx server. (Default: http://localhost:8086)
user-name: myusername # Login user of the Influx server.
默认,Spring 内置的 metrics 都会进行采集,包括:JVM,System,Process,Tomcat,JDBC,Logback …
可以通过下列方式,进行定制化配置:
management.metrics.enable.jvm=false
management.metrics.enable.jvm.memory=true
上面的配置,只会将 jvm.memory 相关的指标保存到 influx db 中,包括:
下面,实现一个测试类,会创建一个 Counter meter,并将指标数据存储到 InfluxDB 中:
@Component
public class CounterMeterTest{
@Autowired
private MeterRegistry registry;
private Counter counter;
@PostConstruct
public void test(){
this.counter = registry.counter("monitor.test.counter");
new Thread(
()->{
try(){
Thread.sleep(10_000);
this.counter.increment(Math.random());
} catch(Exception e){System.out.println("error");}
}
).start();
}
}