⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 网络 「网络」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

千分尺简介

Micrometer 的性能数据为 Java 平台提供了一个上一个监控器的 API,应用程序需要负责 Micrometer 的 API 来收集性能指标。Micrometer 会通用与不同监控器系统的工作只为收集使用。 Micrometer 还很容易支持监控系统中的数据。Micrometer 到类似多个不同的不同的系统中的Micrometer。

Micrometer 目前支持的监控系统有:

https://micrometer.io/docs

千分尺里面有两个最核心的概念,分别是计量器(Meter)和计量器(MeterRegistry),下面来分别看下这个概念。

计量器(米)

Meter收集Metris)性能指标,数据有几种类型的Meter,分别是Counter,Gauge,Timer,Summary。

Meter 有自己的标签,同时 Meter 可以指定每个标签。标签是 key-value 的出现形式,我们就可以根据 tag 对指标进行过滤。除了 Meter 有自己的标签外,也可以可以通过 MeterRegistry 添加通用的标签。

MeterRegistry.Config config = simpleMeterRegistry.config();
config.commonTags("tag1","value1","tag2","value2");

柜台

计数器只增加值,计数器所允许的计数值是双倍类型,默认情况下增加值是 1.0

@Autowired
private SimpleMeterRegistry simpleMeterRegistry;

@Bean
public Counter counter1(){
return Counter.builder("test.count1").register(simpleMeterRegistry);
}

@Bean
public Counter counter2(){
return simpleMeterRegistry.counter("test.count2");
}

@Test
public void test(){
counter1.increment();
}

测量

Cauge 是表示自己的变化,例如温度,压力。与计数器的不同,Gauge 的值不总是增加的

public void guage(){
Gauge.builder("guaua1", this::getValue).register(simpleMeterRegistry);
}

public double getValue(){
return ThreadLocalRandom.current().nextDouble();
}

Gauge对象被创建,就不能手动对其中的值进行修改。在每次显示当前值时, Gauge对象会被创建

定时器

Timer 通常使用记录的一种不同的持续时间。Timer 事件记录可提供的数据,事件的数量和总的持续时间。Timer 的第一种方式来记录持续时间。时间记录方式是使用记录()方法来记录运行对象的运行时间和可调用方式是使用时间。示例来保存状态集

public void record(){
Timer timer = simpleMeterRegistry.timer("record");
timer.record(() -> {
try {
Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
});
}

public void sample(){
Timer.Sample sample = Timer.start();
new Thread(()->{
try {
Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
sample.stop(simpleMeterRegistry.timer("sample"));
});
}

概括

摘要记录指标的分布,摘要根据每个指标的值,把值分配到使用的桶中。微米默认桶的值如果从1到Long.MAX_VALUE,可以通过minimumExpectedValue和maximumExpectedValue来控制桶的范围,指标的数值指标,还可以通过设定一个数值对数值进行放大

public void summary(){
DistributionSummary summary = DistributionSummary.builder("summary")
.maximumExpectedValue(10L)
.minimumExpectedValue(1L)
.publishPercentiles(0.5, 0.75, 0.9)
.register(simpleMeterRegistry);

summary.record(1.0);
summary.record(5.0);
summary.record(4.5);
summary.record(3.0);

System.out.println(summary.takeSnapshot());
}

计量器(MeterRegistry)

MeterRegistry 负责创建和维护Meter。每个监控系统都有自己独立的注册表。

其中是一个基于远程监控的本地监控,它不支持导出到数据系统,主要用于开发和测试。

Micrometer支持多个不同的监控系统,系统可以通过MeterRegistry把多个不同的监控系统组合起来。

public void compositeRegistry(){
CompositeMeterRegistry compositeMeterRegistry = new CompositeMeterRegistry();
compositeMeterRegistry.add(new SimpleMeterRegistry());
compositeMeterRegistry.add(new SimpleMeterRegistry(new SimpleConfig() {
@Override
public String get(String s) {
return null;
}

//增加前缀
@Override
public String prefix() {
return "simple";
}
},Clock.SYSTEM));

Counter counter = compositeMeterRegistry.counter("test");
counter.increment();
}

千分尺本身提供了一个有效的量程度量。

public void globalRegistry(){
Metrics.addRegistry(simpleMeterRegistry);
Counter global = Metrics.counter("global");
global.increment();
}

SpringBoot 执行器

上面介绍了Micrometer的一些简单使用,从Spring Boot2.0开始,Micrometer就是Spring Boot默认提供的性能指标收集库。SpringBoot Actuator提供了对Micrometer的自动配置。在项目中引入SpringBoot Actuator,

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

并在配置文件中,增加配置

Actuator可对外默认的服务,*表示显示所有
management.endpoints.web.exposure.include=*

启动项目,访问 http://8080/actuator,就可以看到Actuator提供的所有监控

{
"_links": {
"self": {
"href": "http://localhost:8080/actuator",
"templated": false
},
"auditevents": {
"href": "http://localhost:8080/actuator/auditevents",
"templated": false
},
"beans": {
"href": "http://localhost:8080/actuator/beans",
"templated": false
},
"caches-cache": {
"href": "http://localhost:8080/actuator/caches/{cache}",
"templated": true
},
"caches": {
"href": "http://localhost:8080/actuator/caches",
"templated": false
},
"health": {
"href": "http://localhost:8080/actuator/health",
"templated": false
},
"health-component": {
"href": "http://localhost:8080/actuator/health/{component}",
"templated": true
},
"health-component-instance": {
"href": "http://localhost:8080/actuator/health/{component}/{instance}",
"templated": true
},
"conditions": {
"href": "http://localhost:8080/actuator/conditions",
"templated": false
},
"configprops": {
"href": "http://localhost:8080/actuator/configprops",
"templated": false
},
"env": {
"href": "http://localhost:8080/actuator/env",
"templated": false
},
"env-toMatch": {
"href": "http://localhost:8080/actuator/env/{toMatch}",
"templated": true
},
"info": {
"href": "http://localhost:8080/actuator/info",
"templated": false
},
"loggers": {
"href": "http://localhost:8080/actuator/loggers",
"templated": false
},
"loggers-name": {
"href": "http://localhost:8080/actuator/loggers/{name}",
"templated": true
},
"heapdump": {
"href": "http://localhost:8080/actuator/heapdump",
"templated": false
},
"threaddump": {
"href": "http://localhost:8080/actuator/threaddump",
"templated": false
},
"prometheus": {
"href": "http://localhost:8080/actuator/prometheus",
"templated": false
},
"metrics": {
"href": "http://localhost:8080/actuator/metrics",
"templated": false
},
"metrics-requiredMetricName": {
"href": "http://localhost:8080/actuator/metrics/{requiredMetricName}",
"templated": true
},
"scheduledtasks": {
"href": "http://localhost:8080/actuator/scheduledtasks",
"templated": false
},
"httptrace": {
"href": "http://localhost:8080/actuator/httptrace",
"templated": false
},
"mappings": {
"href": "http://localhost:8080/actuator/mappings",
"templated": false
}
}
}

访问 http://localhost:8080/actuator/metrics,可以看到Actuator默认收集的监控指标,包括JVM相关指标(内存使用,垃圾收集),tomcat相关指标,数据库连接池或系统相关

{
"names": [
"jvm.memory.max",
"jvm.threads.states",
"process.files.max",
"jvm.gc.memory.promoted",
"system.load.average.1m",
"jvm.memory.used",
"jvm.gc.max.data.size",
"jvm.gc.pause",
"jvm.memory.committed",
"system.cpu.count",
"logback.events",
"tomcat.global.sent",
"jvm.buffer.memory.used",
"tomcat.sessions.created",
"jvm.threads.daemon",
"system.cpu.usage",
"jvm.gc.memory.allocated",
"tomcat.global.request.max",
"tomcat.global.request",
"tomcat.sessions.expired",
"jvm.threads.live",
"jvm.threads.peak",
"tomcat.global.received",
"process.uptime",
"tomcat.sessions.rejected",
"process.cpu.usage",
"http.server.requests",
"tomcat.threads.config.max",
"jvm.classes.loaded",
"jvm.classes.unloaded",
"tomcat.global.error",
"tomcat.sessions.active.current",
"tomcat.sessions.alive.max",
"jvm.gc.live.data.size",
"tomcat.threads.current",
"process.files.open",
"jvm.buffer.count",
"jvm.buffer.total.capacity",
"tomcat.sessions.active.max",
"tomcat.threads.busy",
"process.start.time"
]
}

我们可以通过下面的链接来查看具体的各项指标

http://localhost:8080/actuator/metrics/metricName

其中metricName为需要查看指标的名称,例如查看jvm内存

http://localhost:8080/actuator/metrics/jvm.memory.used

从图片可以看到jvm.memory.used标签,area和id,指定内存(堆内存和堆内存),id指定内存分类来查看我们更多的位置

http://localhost:8080/actuator/metrics/jvm.memory.used?tag=area:heap
http://localhost:8080/actuator/metrics/jvm.memory.used?tag=area:heap&tag=id:PS%20Eden%20Space

普罗米修斯

千分尺支持Pro,千分尺提供给ProMeterRegistry的Pro,将指标转为引入用于支持Prometheus格式的指标。首先需要在pom文件中

<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

在配置文件中,配置暴露 Protheus,并允许将我的列表导入到 Prometheus 中

management.endpoint.prometheus.enabled=true
management.metrics.export.prometheus.enabled=true

项目启动后,我们访问 http://localhost:8080/actuator/prometheus,可以看到指标以变成Prometheus格式的指标。

可以安装Prometheus来采集这些指标

docker run -d -p 9090:9090 -v ~/Documents/config/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus

其中promeus.yml配置了采集地址及路径

scrape_configs:
- job_name: prometheus-test
metrics_path: /actuator/prometheus
static_configs:
- targets: ['172.16.22.50:8080']

172.16.22.50是修改我本机的地址,你们可以为自己的ip地址自动访问,访问 http://localhost:9090/targets 可以看到Prometheus的采集配置

自定义公制

我们利用 Prometheus 客户端可以自定义metric

package com.wbl.spingbootdemo.prometheus;

import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.Counter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;


@Service
public class PrometheusMeter {

@Autowired
private CollectorRegistry collectorRegistry;

// 定义name为prometheus_counter的counter
public Counter prometheusCounter(){
return Counter.build().name("prometheus_counter").help("prometheus counter test")
.register(collectorRegistry);
}

@PostConstruct
public void init(){
Counter counter = prometheusCounter();
new Thread(()-> {
while (true){
counter.inc();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}

启动项目之后,可以在Prometheus查询页面看到刚刚定义的指标prometheus_counter

总结

  1. Micrometer集成了多个监控系统,包括Prometheus。Micrometer利用Meter收集数据,利用不同的MeterRegistry与不同的监控系统集成
  2. SpringBoot Actuator集成了Micrometer,定义了默认的metric,可以在 http://localhost:8080/actuator/metrics 查看
  3. SpringBoot Actuator可以通过Micrometer将采集的指标导入Prometheus中
文章目录
  1. 1. 千分尺简介
    1. 1.0.1. 计量器(米)
    2. 1.0.2. 柜台
    3. 1.0.3. 测量
    4. 1.0.4. 定时器
    5. 1.0.5. 概括
    6. 1.0.6. 计量器(MeterRegistry)
  • 2. SpringBoot 执行器
  • 3. 普罗米修斯
  • 4. 自定义公制
  • 5. 总结