Jvm-指标收集
收集指标
1
JMX Exporter
JMX Exporter 简介
Java Management Extensions,JMX 是管理 Java 的一种扩展框架,JMX Exporter 基于此框架读取 JVM 的运行时状态。JMX Exporter 利用 Java 的 JMX 机制来读取 JVM 运行时的监控数据,然后将其转换为 Prometheus 可辨识的 metrics 格式,以便让 Prometheus 对其进行监控采集。
启动方式
启动独立进程
JVM 启动时指定参数,暴露 JMX 的 RMI 接口。JMX Exporter 调用 RMI 获取 JVM 运行时状态数据,转换为 Prometheus metrics 格式,并暴露端口让 Prometheus 采集。
备注: 官方不建议使用启动独立进程方式
JVM 进程内启动(in-process)
JVM 启动时指定参数,通过 javaagent 的形式运行 JMX Exporter 的 jar 包,进程内读取 JVM 运行时状态数据,转换为 Prometheus metrics 格式,并暴露端口让 Prometheus 采集
启用 jmx-exporter
1.下载jar包
2.启动命令
获取两个文件的绝对或相对路径
- jar包: /data/jmx_prometheus_javaagent-1.0.1.jar
- 配置文件: /data/jmx-config.yaml
1 java -javaagent:/data/jmx_prometheus_javaagent-1.0.1.jar=8080:/data/config.yaml -jar yourJar.jar8080: 暴露指标的接口
jmx-config.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
---
lowercaseOutputLabelNames: true
lowercaseOutputName: true
whitelistObjectNames:
- "java.lang:*" # 抓取 JVM 通用的 MBeans
- "com.sun.management:type=HotSpotDiagnostic" # 热点 JVM 特定的 MBeans
- "com.zaxxer.hikari:type=Pool (apollo*)" # 抓取 Apollo 中 HikariCP 连接池的 MBeans
rules:
# 匹配 JVM 内存相关的指标
- pattern: "java.lang:type=MemoryPool,name=(.*)"
name: jvm_memory_pool_$1
type: GAUGE
labels: {}
help: "JVM memory pool"
- pattern: "java.lang:type=GarbageCollector,name=(.*)"
name: jvm_gc_$1
type: COUNTER
labels: {}
help: "JVM Garbage Collection"
# 匹配线程信息
- pattern: "java.lang:type=Threading"
name: jvm_threads
type: GAUGE
attrNameSnakeCase: true
help: "JVM Threads"
# 匹配操作系统级的 CPU 使用和内存信息
- pattern: "java.lang:type=OperatingSystem"
name: os_$1
type: GAUGE
labels: {}
attrNameSnakeCase: true
help: "Operating System Metrics"
# 匹配 HikariCP 连接池的指标(如果 Apollo 使用 HikariCP)
- pattern: "com.zaxxer.hikari:type=Pool (.*),name=.*,.*=(.*)"
name: hikari_pool_$1_$2
type: GAUGE
labels: {}
help: "HikariCP connection pool metrics"
1 2 3 4 type: 规则其他常见类型 COUNTER:计数器类型,只会递增,比如请求次数、错误次数。 HISTOGRAM:统计一段时间内的值分布(包括计数和观察到的样本)。 SUMMARY:类似于 HISTOGRAM,但更多地用于计算分位数。
使用jconsole 或 jvisualvm 连接远程 JVM
安装依赖环境-java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# MacOS:
brew install openjdk@11
## 安装后,根据提示,设置环境
echo 'export PATH="/opt/homebrew/opt/openjdk@11/bin:$PATH"' >> /Users/FengYLBook/.bash_profile
export CPPFLAGS="-I/opt/homebrew/opt/openjdk@11/include"
sudo ln -sfn /opt/homebrew/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk
# Linux:
apt install openjdk-11-jdk
yum install openjdk-11-jdk
服务端开启 jmx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 保证java开启了JMX,启动参数
-Dcom.sun.management.jmxremote # 启用 JMX
-Dcom.sun.management.jmxremote.port=PORT # 设定远程 JMX 监听端口(需要替换为实际端口号,如 12345)
-Dcom.sun.management.jmxremote.rmi.port=PORT # 用于 RMI 连接的端口(通常和 JMX 端口相同)
-Dcom.sun.management.jmxremote.authenticate=false # 禁用 JMX 认证(生产环境不建议禁用)
-Dcom.sun.management.jmxremote.ssl=false # 禁用 SSL 加密(生产环境不建议禁用)
-Djava.rmi.server.hostname=HOST # 绑定的主机名或 IP 地址(需要替换为实际的主机名或 IP 地址)
# eg:
-Dcom.sun.management.jmxremote # 启用 JMX
-Dcom.sun.management.jmxremote.port=8080
-Dcom.sun.management.jmxremote.rmi.port=8080
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=172.31.25.29
启动 jconsole
1 2# 终端执行 jconsole
实践apollo接jmx-exporter
apollo 启动脚本更改
1
2
3
4
5
6
7
8
9
10
# /apollo-*/script/startup.sh
...
# 使用 eval 将系统环境变量 替换并覆盖 prometheus-jmx-config.yaml 中同名变量
# 如上 ${MY_SVC_NAME}、${MY_POD_NAME}、${POD_IP}
eval "cat <<EOF
$(< /prometheus-jmx-config.yaml )
EOF" > /prometheus-jmx-config.yaml
...
prometheus-jmx-config.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#hostPort: "apollo-configservice-hl.md:8080" # 远程主机的IP和JMX监听端口(使用独立jmx-exporter进程连接远程 jvm进程时使用)
lowercaseOutputName: true
lowercaseOutputLabelNames: true
#whitelistObjectNames:
# - "java.lang<type=(.*)>" # 抓取 JVM 通用的 MBeans
# - "com.sun.management:type=HotSpotDiagnostic" # JVM 特定的 MBeans
rules:
# 匹配 JVM 内存相关的指标
- pattern: "java.lang<type=MemoryPool, name=(.+)><(.+)>(.+):(.+)"
name: jvm_memory_pool_\$2_\$3
type: GAUGE
labels:
application: "${MY_SVC_NAME}"
pool: "\$1"
pod_name: "${MY_POD_NAME}"
pod_ip: "${POD_IP}"
help: "JVM memory pool"
- pattern: "java.lang<type=Runtime>(.+)"
name: process_uptime_seconds
labels:
application: "${MY_SVC_NAME}"
pod_name: "${MY_POD_NAME}"
pod_ip: "${POD_IP}"
type: GAUGE
attrNameSnakeCase: true # 将属性名转换为蛇形命名
help: "Process uptime in seconds"
- pattern: "java.lang<type=GarbageCollector, name=(.+)><>CollectionCount"
name: jvm_gc_collectioncount
type: COUNTER
labels:
name: "\$1"
application: "${MY_SVC_NAME}"
pod_name: "${MY_POD_NAME}"
pod_ip: "${POD_IP}"
help: "JVM Garbage Collection"
- pattern: "java.lang<type=GarbageCollector, name=(.+)><>CollectionTime"
name: jvm_gc_collectiontime
type: COUNTER
labels:
name: "\$1"
application: "${MY_SVC_NAME}"
pod_name: "${MY_POD_NAME}"
pod_ip: "${POD_IP}"
help: "JVM Garbage Collection"
- pattern: "java.lang<type=GarbageCollector, name=(.+), key=(.+)><LastGcInfo, (.+)>(.+)"
name: jvm_gc_lastgcinfo
labels:
name: "\$1"
key: "\$2"
status: "\$3"
application: "${MY_SVC_NAME}"
pod_name: "${MY_POD_NAME}"
pod_ip: "${POD_IP}"
help: "JVM Garbage Collection"
# 匹配线程信息
- pattern: "java.lang<type=Threading>(.+)"
name: jvm_threads
labels:
application: "${MY_SVC_NAME}"
pod_name: "${MY_POD_NAME}"
pod_ip: "${POD_IP}"
type: GAUGE
attrNameSnakeCase: true
help: "JVM Threads"
# 匹配操作系统级的 CPU 使用和内存信息
- pattern: "java.lang<type=OperatingSystem>(.+)"
name: os_system
labels:
application: "${MY_SVC_NAME}"
pod_name: "${MY_POD_NAME}"
pod_ip: "${POD_IP}"
type: GAUGE
attrNameSnakeCase: true
help: "Operating System Metrics"
apollo 服务启动引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 以 k8s pod 为准 接入 apollo-configservice
spec:
template:
metadata:
labels:
app: apollo-configservice
spec:
containers:
- env:
- name: POD_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
- name: MY_POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: MY_SVC_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.labels['app']
- name: JAVA_OPTS
value: ...
-javaagent:/apollo-configservice/jmx_prometheus_javaagent-1.0.1.jar=8080:/prometheus-jmx-config.yaml
...
本文由作者按照
CC BY 4.0
进行授权