1 SpringBoot监控方式
jmx_exporter 主要⽤于从 Java 应⽤程序中提取 JMX 指标,通常包括 JVM级别的信息,如内存使⽤情况、线程状态、垃圾回收次数等。
● 对于传统的SpringBoot应⽤,由于它默认没有内置 Prometheus 监控的指标,因此使⽤ jmx_exporter来抓取基础的JVM相关指标。
● 如果想要获取更细粒度的应⽤级别的业务指标,例如HTTP请求数、处理时间或业务操作的计数,则需要在应⽤中集成Prometheus客户端库,并⾃定义相应的指标。
2 jmx-exporter
2.1 下载jmx-exporter
1、访问github
https://github.com/prometheus/jmx_exporter/releases ,下载java-expoter
下载地址
https://repo.maven.apache.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/
下载
mkdir /app/module/jmx_exporter
cd /app/module/jmx_exporter/
wget https://repo.maven.apache.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.20.0/jmx_prometheus_javaagent-0.20.0.jar
2、准备config.yml配置⽂件(规则⽂件可以定义要暴露哪些指标给
Prometheus)
cat /app/module/jmx_exporter/config.yml
rules:
- pattern: ".*"
2.2 运⾏SpringBoot应⽤
运⾏java应⽤,并加载jmx监控,监听12345端⼝, <path_to_jmx_exporter.jar>=<exporter_port>:<path_to_config.yaml>
java -javaagent:/app/module/jmx_exporter/jmx_prometheus_javaagent-0.20.0.jar=12345:/app/module/jmx_exporter/config.yml -jar demo-service-1.0.jar
#如果想绑定IP
java -javaagent:/app/module/jmx_exporter/jmx_prometheus_javaagent-0.20.0.jar=192.168.137.131:12345:/app/module/jmx_exporter/config.yml -jar demo-service-1.0.jar
2.3 配置Prometheus
1、修改Prometheus配置
- job_name: "jmx_exporter"
metrics_path: "/metrics"
static_configs:
- targets: ["192.168.137.131:12345"]
2、重新加载Prometheus配置⽂件
curl -X POST http://192.168.137.131:9090/-/reload
2.4 JMX常⽤指标与示例
2.4.1 JVM内存使⽤相关指标
Tomcat也有这些指标
指标名称 | 指标 类型 | 指标含义 |
vm_memory_bytes_init{area="heap",} | gauge | JVM 初始堆内存⼤⼩(单位字节。) |
jvm_memory_bytes_used{area="heap",} | gauge | JVM 已使⽤内存(单位字节。)。 |
jvm_memory_bytes_max{area="heap",} | gauge | JVM 最⼤可⽤内存(单位字节。)。 |
jvm_gc_collection_seconds_count | counter | JVM启动以来发⽣的垃圾回收事件的总次数(⽐如YoungGC、OldGC) |
jvm_gc_collection_seconds_sum | counter | JVM启动以来所有垃圾回收事件所花费的总时间(以秒为单位) |
jvm_threads_deadlocked | gauge | JVM死锁线程数。 |
jvm_threads_state | gauge | JVM线程,按状态进⾏分类计数。例如: NEW、WAITING、TIMED_WAITING等分类 |
案例1:存活检测
up{job="jmx_exporter"} == 0
案例2:JVM堆内存使⽤率。计算公式:已⽤堆内存
jvm_memory_bytes_used{area="heap"} / jvm_memory_bytes_max{area="heap"} * 100
案例3:计算JVM,新⽣代和⽼年代,每次GC所需时间,因为这两个指标是不断累积的
因此计算公式:rate(JVMGC花费总时间[1m]) / rate(JVMGC总次数[1m])
# 如果jvm_gc_collection_seconds_count是100次,⽽jvm_gc_collection_seconds_sum是50秒,那么平均每次GC耗时是0.5秒。
sum (rate(jvm_gc_collection_seconds_sum[5m]) / rate(jvm_gc_collection_seconds_count[5m])) by (gc, instance, job)
案例4:计算JVM最近5分钟,最⼩的死锁线程数,是否⾼于10
min_over_time(jvm_threads_deadlocked[5m])
2.4.2 JVM堆内存分配相关指标
可以查看新⽣代、⽼年代分别使⽤了多少内存,粒度更细⼀些
指标名称 | 指标 类型 | 指标含义 |
jvm_memory_pool_bytes_used | gauge | JVM内存池中当前已使⽤的内存量(以字节为单位) |
jvm_memory_pool_bytes_max | gauge | JVM内存池可以达到的最⼤内存量 (以字节为单位) |
2.5 JMX告警规则⽂件
2.5.1 告警规则⽂件
vim /app/module/prometheus/rules/jvm_rules.yml
groups:
- name: "JVM告警规则"
rules:
- alert: JVM堆内存使用率过高
expr: jvm_memory_bytes_used{area="heap",} / jvm_memory_bytes_max{area="heap",} * 100 > 80
for: 1m
labels:
severity: critical
annotations:
summary: "JVM 堆内存使用率过高, 实例:{{ $labels.instance }}, job:{{ $labels.job }} "
description: "JVM堆内存使用率超过80%, 当前值 {{ $value }}%"
- alert: JVMGC时间过长
expr: sum (rate(jvm_gc_collection_seconds_sum[5m]) / rate(jvm_gc_collection_seconds_count[5m])) by (gc, instance, job) > 1
for: 1m
labels:
severity: critical
annotations:
summary: "JVM GC时间过长, 实例:{{ $labels.instance }}, job:{{ $labels.job }} "
description: "JVM {{ $labels.gc }} 的回收时间超过1s,当前值 {{ $value }}s"
- alert: JVM死锁线程过多
expr: min_over_time(jvm_threads_deadlocked[5m]) > 0
for: 1m
labels:
severity: critical
annotations:
summary: "JVM检测到死锁线程"
description: "在过去5分钟内JVM检测到存在死锁线程, 当前值 {{ $value }}。"
2.5.2 检测rules语法
/app/module/prometheus/promtool check rules /app/module/prometheus/rules/jvm_rules.yml
2.5.3 重新加载Prometheus
curl -X POST http://192.168.137.131:9090/-/reload
2.5.4 验证规则⽂件
2.6 导⼊JMX图形
导⼊⼀个JVM的Grafana模板。Dashboard ID为 14845