1. JMX(Java Management Extensions)是什么?
JMX(Java 管理扩展)是 Java 内置的一套监控和管理框架,允许开发者 远程或本地 监控 Java 应用的状态,包括:
- JVM 运行时信息(内存、CPU、线程、GC 等)
- MBeans(管理对象)(应用内部的业务指标)
- JVM 调优(动态修改参数、触发 GC)
JMX 主要由三部分组成:
- MBean(管理 Bean):提供具体的监控指标和管理接口(类似 API)。
- MBeanServer(管理服务):存储和管理所有 MBean。
- Connector(连接器):
- JMX Remote(RMI)远程管理
- JMX Exporter 通过 HTTP 提供
/metrics
,供 Prometheus 采集
2. JMX Remote vs JMX Exporter
特性 | JMX Remote(JConsole 方式) | JMX Exporter(Prometheus 方式) |
---|---|---|
用途 | 远程管理 JVM(手动排查问题) | 监控 JVM 指标(自动采集) |
连接方式 | RMI 远程连接(JConsole、VisualVM) | HTTP /metrics (Prometheus 采集) |
端口 | -Dcom.sun.management.jmxremote.port=XXXX | -javaagent:jmx_prometheus_javaagent.jar=XXXX:/config.yaml |
安全性 | 较低(暴露 RMI,容易被攻击) | 较高(只暴露 HTTP,受 Kubernetes 控制) |
自动化 | ❌ 手动连接,运维成本高 | ✅ 自动发现,适合集群监控 |
Grafana 展示 | ❌ 需要额外插件 | ✅ 原生支持 |
性能损耗 | 高(每次远程连接都会占用 JVM 资源) | 低(Prometheus 以 HTTP 方式拉取,不影响 JVM) |
3. JMX Remote 和 Exporter 使用场景
使用场景 | 推荐方案 |
---|---|
本地开发 & 调试 JVM 性能 | JMX Remote (JConsole/VisualVM 远程连接) |
线上排查 GC、死锁问题 | JMX Remote (但需要安全加固) |
Prometheus/Grafana 监控 JVM | JMX Exporter (自动采集,不影响业务) |
Kubernetes 集群 Java 监控 | JMX Exporter (通过 ServiceMonitor 采集) |
4. JMX 对 JVM 性能的损耗
影响因素
1. JMX Remote
- 远程连接会消耗 CPU 和内存,影响 JVM 运行。
- 若启用过多 MBeans,会增加 JVM 负担。
- JConsole/VisualVM 持续连接,会导致 GC 频繁,影响业务。
- 性能影响: 约 5% ~ 10%,高并发情况下更严重。
2. JMX Exporter
- HTTP
/metrics
方式,性能开销小。 - Prometheus 拉取间隔可控(默认 30s~60s,不会持续占用资源)。
- 性能影响: 小于 1%,对应用基本无影响。
5. 如何最终选择?
需求 | 建议方案 |
---|---|
需要 手动排查 JVM 细节(线程、GC、HeapDump) | JMX Remote(短时间连接,远程调试) |
需要 Prometheus & Grafana 监控,自动化监控 JVM | JMX Exporter(低开销,适合生产环境) |
需要 线上 Java 服务的长期监控 | JMX Exporter + Prometheus + Grafana |
只需要 监控几个关键指标(比如 Heap、GC) | 直接用 Spring Boot Actuator 或 JVM Micrometer |
6. 生产环境最佳实践
✅ 如果只是监控 Java 进程,推荐 JMX Exporter
:
-javaagent:/opt/jmx_prometheus/jar/jmx_prometheus_javaagent-0.18.0.jar=10080:/opt/jmx_prometheus/conf/config.yaml
最终方案(推荐 )
✅ 生产环境:JMX Exporter + Prometheus + Grafana,不暴露 JMX Remote,提高安全性
✅ GC 调试:jcmd / jstat / jmap / jstack 即插即用,无需额外开放端口
✅ OOM / 性能问题分析:jmap Dump + MAT 工具分析
7.示例配置
同时启用remote和exporter
exec java $JAVA_OPTS -Dloader.path=/config/ \
-XX:+UseG1GC -XX:MaxGCPauseMillis=200 \
-XX:-OmitStackTraceInFastThrow \
-javaagent:/opt/jmx_prometheus/jar/jmx_prometheus_javaagent-0.18.0.jar=10080:/opt/jmx_prometheus/conf/config.yaml \
-Dlog4j.formatMsgNoLookups=true \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=10081 -Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Djava.security.egd=file:/dev/./urandom -jar /app/cms-server.jar
如果只启用exporter
-javaagent:/opt/jmx_prometheus/jar/jmx_prometheus_javaagent-0.18.0.jar=10080:/opt/jmx_prometheus/conf/config.yaml
为了替代JMX Remote我们可以使用阿里开源的arthas
https://arthas.aliyun.com/
只需要下载包以后java -jar启动 就可以查看更详细的jvm信息