利用 OpenTelemetry 集成 JMX 监控

JMX 是 Java 应用暴露运行时指标的常见方式。本文以 Tomcat 为例,说明如何通过 OpenTelemetry JMX Scraper、OpenTelemetry Java Agent 和 OpenTelemetry Collector JMX Receiver 三种方式采集 JMX 指标。

作者 Alex Boten

JMX(Java Management Extensions)是 Java 平台提供的标准管理扩展,很多 Java 应用会通过 JMX 暴露运行时指标。OpenTelemetry 可以把这些 JMX 指标接入统一遥测管道,便于后续导出到控制台、OTLP 后端或其他可观测性系统。

核心要点

  • JMX 可以理解为 Java 应用暴露运行时指标和管理能力的一种标准方式。
  • OpenTelemetry 集成 JMX 有三种常见方法:JMX Scraper、OpenTelemetry Java Agent、OpenTelemetry Collector JMX Receiver。
  • JMX Scraper 适合快速测试;Java Agent 适合已经使用自动 instrumentation 的 Java 应用;Collector 适合把采集能力放在应用外部。
  • 三种方式都依赖规则配置,将 JMX MBean 映射为 OpenTelemetry 指标。
  • 自定义应用不在预定义支持列表中时,需要编写自定义 rules 配置。

JMX 是什么

JMX 是 Java Management Extensions 的缩写,中文通常称为 Java 管理扩展。它是 Java 平台提供的一套标准框架,用于对 Java 应用程序、设备和系统资源进行监控与管理。

JMX 的核心作用包括:

  • 监控 Java 程序运行状态,例如内存使用、线程数、类加载情况。
  • 动态修改配置参数,避免部分场景下重启应用。
  • 通过 JConsole、VisualVM 等工具远程管理 Java 应用。
  • 集成到监控系统中,实现对 JVM 和 Java 中间件的集中监控。

很多 Java 应用,例如 Kafka、Hadoop、Tomcat,都通过 JMX 暴露运行时指标,方便运维人员监控和排障。在监控语境下,可以把 JMX 简单理解为 Java 应用暴露指标的一种标准方式。

很多新项目会直接暴露 Prometheus 协议指标,这确实更方便。但不少存量 Java 应用仍通过 JMX 暴露指标,因此掌握 JMX 监控方式,等于掌握一批 Java 应用的监控入口。

OpenTelemetry 如何接入 JMX

OpenTelemetry 的标准已经被业界普遍使用,JMX 也可以与 OpenTelemetry 集成。OpenTelemetry 的 JMX 集成会使用 YAML 配置描述应用指标如何转换为 OpenTelemetry 指标。这些规则提供给与 JMX API 交互的 JMX 指标抓取工具。

许多 Java 应用可以通过 JMX 发出指标。原文提到,以下应用已有社区支持的预定义规则文件:

  • Activemq
  • Cassandra
  • Hbase
  • Hadoop
  • Jetty
  • Jvm
  • Kafka
  • Solr
  • Tomcat
  • Wildfly

这意味着,使用 JMX 抓取工具时,可以把目标应用识别为上述系统之一,在无需额外自定义规则的情况下自动抓取指标。

三种集成方式对比

方式 适合场景 特点
JMX Scraper 本地测试、快速验证 JMX 指标可用性 依赖少,启动快,需要额外 JAR
OpenTelemetry Java Agent 应用已经使用 Java Agent 做自动 instrumentation 指标、日志、链路可统一接入,但会引入 agent 开销
OpenTelemetry Collector JMX Receiver 希望在应用外部采集,或已有 Collector 遥测管道 灵活,可做转换和导出,但需要 Collector 配置和 scraper JAR

本文以 Tomcat 为例,分别展示三种方式。

准备:暴露 Tomcat 的 JMX 端口

在深入 OpenTelemetry 集成前,需要确保测试应用已正确暴露 JMX 端点。下面命令在 Docker 容器中启动 Tomcat,以减少本地依赖。它通过 JAVA_OPTS 启用 JMX,并让 JMX 在 9999 端口可用。

$ docker run -it --rm -p 9999:9999 -p 8888:8080 -e JAVA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.rmi.port=9999 -Djava.rmi.server.hostname=0.0.0.0 -Dcom.sun.management.jmxremote.ssl=false" tomcat:9.0

可以用 JConsole 验证 JMX 端口是否可访问:

$ jconsole localhost:9999

JConsole 会弹出应用窗口,可能提示连接不安全。本地开发时可以忽略这个警告。

JConsole

确认数据可以通过远程 JMX 端口访问后,就可以开始接入 OpenTelemetry。

方法一:直接使用 JMX Scraper

JMX Scraper 是最简单的入门方式。下面命令会:

  1. 从 Maven 下载 JMX Scraper 发布版本。
  2. 运行 JMX Scraper,从 Tomcat 通过 JMX 收集指标。
  3. 将指标输出到本地控制台。
$ wget https://repo1.maven.org/maven2/io/opentelemetry/contrib/opentelemetry-jmx-scraper/1.49.0-alpha/opentelemetry-jmx-scraper-1.49.0-alpha.jar

$ OTEL_METRICS_EXPORTER=console java -jar opentelemetry-jmx-scraper-1.49.0-alpha.jar -config - <<EOF
otel.jmx.service.url=service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi
otel.jmx.target.system=tomcat
EOF

命令输出会显示连接已经建立,并且相关 metric instrument 已创建:

WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::objectFieldOffset has been called by io.opentelemetry.internal.shaded.jctools.util.UnsafeAccess (file:/Users/alex/Downloads/opentelemetry-jmx-scraper-1.49.0-alpha.jar)
WARNING: Please consider reporting this to the maintainers of class io.opentelemetry.internal.shaded.jctools.util.UnsafeAccess
WARNING: sun.misc.Unsafe::objectFieldOffset will be removed in a future release
2025-08-27 10:28:48 INFO metrics export interval (seconds) =  60
2025-08-27 10:28:48 WARNING SASL unsupported in current environment: class io.opentelemetry.contrib.jmxscraper.JmxConnectorBuilder cannot access class com.sun.security.sasl.Provider (in module java.security.sasl) because module java.security.sasl does not export com.sun.security.sasl to unnamed module @24313fcc
2025-08-27 10:28:48 INFO Connecting to service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi
2025-08-27 10:28:48 INFO tomcat: found 3 metric rules
2025-08-27 10:28:48 INFO JMX scraping started
2025-08-27 10:28:49 INFO Created Counter for tomcat.error.count
2025-08-27 10:28:49 INFO Created Counter for tomcat.request.count
2025-08-27 10:28:49 INFO Created Gauge for tomcat.request.duration.max
2025-08-27 10:28:49 INFO Created Counter for tomcat.request.duration.sum
2025-08-27 10:28:49 INFO Created Counter for tomcat.network.io
2025-08-27 10:28:49 INFO Created Counter for tomcat.network.io
2025-08-27 10:28:49 INFO Created UpDownCounter for tomcat.thread.count
2025-08-27 10:28:49 INFO Created UpDownCounter for tomcat.thread.limit
2025-08-27 10:28:49 INFO Created UpDownCounter for tomcat.thread.busy.count

JMX Scraper 很适合快速验证,但它需要额外 JAR。如果环境已经使用 OpenTelemetry Java Agent,可能更倾向于下一种方式。

方法二:使用 OpenTelemetry Java Agent

OpenTelemetry Java Agent 除了提供 JMX 集成,还能自动检测 Java 应用。因为它能同时覆盖 traces、metrics、logs 等遥测数据,所以在生产环境中更常见。

下面命令会:

  1. 下载 OpenTelemetry Java Agent jar。
  2. 将本地目录挂载到 Docker 容器。
  3. 用环境变量启动 Tomcat,并加载 agent jar。
$ wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.19.0/opentelemetry-javaagent.jar

$ docker run -it -v `pwd`:/tmp --rm \
  -e OTEL_LOGS_EXPORTER=console \
  -e OTEL_TRACES_EXPORTER=console \
  -e OTEL_METRICS_EXPORTER=console \
  -e CATALINA_OPTS="$CATALINA_OPTS -javaagent:/tmp/opentelemetry-javaagent.jar" \
  -e JAVA_OPTS="-Dcom.sun.management.jmxremote         -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.rmi.port=9999 -Djava.rmi.server.hostname=0.0.0.0 -Dcom.sun.management.jmxremote.ssl=false -Dotel.jmx.target.system=tomcat" \     
  tomcat:9.0

输出会与运行 JMX Scraper 的输出类似:

04-Sep-2025 21:43:40.251 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [48] milliseconds
[otel.javaagent 2025-09-04 21:43:40:787 +0000] [jmx_bean_finder] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Counter for tomcat.error.count
[otel.javaagent 2025-09-04 21:43:40:787 +0000] [jmx_bean_finder] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Counter for tomcat.request.count
[otel.javaagent 2025-09-04 21:43:40:789 +0000] [jmx_bean_finder] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Gauge for tomcat.request.duration.max
[otel.javaagent 2025-09-04 21:43:40:789 +0000] [jmx_bean_finder] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Counter for tomcat.request.duration.sum
[otel.javaagent 2025-09-04 21:43:40:789 +0000] [jmx_bean_finder] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Counter for tomcat.network.io
[otel.javaagent 2025-09-04 21:43:40:789 +0000] [jmx_bean_finder] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Counter for tomcat.network.io
[otel.javaagent 2025-09-04 21:43:40:790 +0000] [jmx_bean_finder] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created UpDownCounter for tomcat.thread.count
[otel.javaagent 2025-09-04 21:43:40:790 +0000] [jmx_bean_finder] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created UpDownCounter for tomcat.thread.limit
[otel.javaagent 2025-09-04 21:43:40:791 +0000] [jmx_bean_finder] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created UpDownCounter for tomcat.thread.busy.count

如果部署已经使用 OpenTelemetry Java Agent,这种方式可以在不引入额外独立采集进程的情况下收集 JMX 指标。

方法三:使用 OpenTelemetry Collector 和 JMX Receiver

第三种方式是使用 OpenTelemetry Collector。Collector 通常作为遥测管道的一部分部署在基础设施内部,负责接收、处理、转换并导出遥测数据。

Collector 的 JMX Receiver 底层使用 JMX Scraper 与 Java 应用交互。下面仍以 Tomcat 为例,使用 OpenTelemetry Collector Contrib 发行版,并配置 debug exporter 将指标输出到控制台。同时示例中还添加了 OTLP exporter,用于将数据发送到 Honeycomb。

receivers:
  jmx/tomcat:
    jar_path: /tmp/opentelemetry-jmx-scraper-1.48.0-alpha.jar
    endpoint: localhost:9999
    target_system: tomcat
    collection_interval: 10s


exporters:
  otlphttp:
    endpoint: https://api.honeycomb.io:443
    headers:
      x-honeycomb-team: ${env:HONEYCOMB_API_KEY}
      x-honeycomb-dataset: jmx-test
   
  debug:
    verbosity: detailed


service:
  telemetry:
    logs:
      level: debug
  pipelines:
    metrics:
      receivers: [jmx/tomcat]
      exporters: [debug, otlphttp]

要让配置生效,需要指定 JMX Scraper JAR 的位置,因为 receiver 本身不包含该 JAR。准备配置后,下载并运行 Collector Contrib:

$ wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.133.0/otelcol-contrib_0.133.0_darwin_arm64.tar.gz -O - | tar -xz
​​$ ./otelcol-contrib --config configuration.yaml

Collector 输出会包含来自 JMX Scraper 的详细信息,以及 debug exporter 的日志,用于验证数据是否按配置导出。

使用 Collector 的好处是,无需修改应用或应用运行环境,只要应用远程暴露 JMX 端口即可。Collector 还可以对数据进行转换、丰富和多路导出。

自定义应用的 JMX 采集

OpenTelemetry 社区支持的应用列表无法覆盖所有 Java 应用。对于自定义应用,需要定义自定义规则配置,把 MBean 属性映射为 OpenTelemetry 指标。

下面示例为 Resin 服务器暴露的指标创建映射。它将 resin 命名空间中 ThreadPool 托管 Bean(MBean)的 JMX 属性 ThreadActiveCount 映射到 OpenTelemetry 中名为 resin.threadpool.active.count 的 gauge:

rules:
 - bean: resin:type=ThreadPool
   type: gauge
   unit: "{thread}"
   mapping:
     ThreadActiveCount:
       metric: resin.threadpool.active.count
       desc: "Current number of active threads in the pool"

三种集成方式都支持自定义配置文件。JMX Scraper 通过 otel.jmx.config 属性支持;Collector 中的 JMX Receiver 可以使用 jmx_configs 替代 target_system

receivers:
  jmx/resin:
    jar_path: /Users/alex/Downloads/opentelemetry-jmx-scraper-1.48.0-alpha.jar
    endpoint: localhost:9999
    jmx_configs: /tmp/resin.rules.yaml
    collection_interval: 10s

落地检查表

检查项 说明
JMX 端口可访问 先用 JConsole 或等价工具确认 JMX 连接可用
target system 正确 Tomcat、Kafka 等预定义系统名称要匹配
scraper JAR 存在 JMX Scraper 和 Collector JMX Receiver 都依赖 JAR
exporter 已配置 console、debug、OTLP 等导出方式需明确
自定义 rules 可维护 自定义 MBean 映射要控制指标命名和标签数量
安全边界清楚 暴露远程 JMX 时要关注认证、网络和端口访问范围

FAQ

已经有 JMX Exporter,还需要 OpenTelemetry 吗?

不一定。JMX Exporter 适合把 JMX 指标暴露为 Prometheus 格式;OpenTelemetry 更适合把指标接入统一遥测管道,并与 traces、logs 或 OTLP 后端结合。选择取决于现有监控体系。

三种方式应该怎么选?

快速验证选 JMX Scraper;应用已经使用 OpenTelemetry Java Agent 时选 Java Agent;希望应用外部统一采集、转换和导出时选 Collector JMX Receiver。

自定义 rules 的关键是什么?

关键是把 MBean 属性映射成语义清晰、命名稳定、标签可控的指标。不要只追求“能采到”,还要保证后续查询、告警和成本可控。

总结

OpenTelemetry 为 JMX 指标提供了三条接入路径:直接运行 JMX Scraper、随应用运行 OpenTelemetry Java Agent、通过 Collector JMX Receiver 在应用外部采集。三种方式都围绕同一个核心动作展开:从 JMX MBean 中读取指标,再按照规则转换为 OpenTelemetry 指标。实际选型时,应结合现有部署方式、是否已有 Agent、是否需要外部采集以及遥测管道治理需求来决定。

原文链接:https://www.honeycomb.io/blog/integrating-jmx-opentelemetry

延伸路径

继续看解决方案和产品对比

如果你正在做监控、可观测性或故障定位相关选型,建议从解决方案和产品对比继续往下看。

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云