利用 OpenTelemetry 集成 JMX 監(jiān)控
JMX 是什么?
JMX 是 “Java Management Extensions” 的縮寫,中文通常稱為 “Java 管理擴(kuò)展”。它是 Java 平臺提供的一套標(biāo)準(zhǔn)框架,用于對 Java 應(yīng)用程序、設(shè)備、系統(tǒng)資源進(jìn)行監(jiān)控和管理。
JMX 的核心作用包括:
- 監(jiān)控 Java 程序運(yùn)行狀態(tài)(如內(nèi)存使用、線程數(shù)、類加載情況等);
- 動態(tài)修改配置參數(shù)(無需重啟應(yīng)用);
- 遠(yuǎn)程管理 Java 應(yīng)用(通過 JConsole、VisualVM 等工具);
- 集成到監(jiān)控系統(tǒng)中,實(shí)現(xiàn)對 JVM 的集中監(jiān)控。
很多 Java 應(yīng)用(如 Kafka、Hadoop、Tomcat 等)都通過 JMX 暴露運(yùn)行時指標(biāo),方便運(yùn)維人員進(jìn)行監(jiān)控和故障排查。在監(jiān)控領(lǐng)域,你就可以簡單的理解 JMX 是一種 Java 應(yīng)用暴露指標(biāo)的標(biāo)準(zhǔn)方式。
很多新的開源項(xiàng)目直接暴露 Prometheus 協(xié)議的監(jiān)控?cái)?shù)據(jù),確實(shí)更方便,但很多老的 Java 應(yīng)用仍然通過 JMX 暴露指標(biāo)數(shù)據(jù),所以掌握 JMX 監(jiān)控方式,等于掌握了一批 Java 應(yīng)用的監(jiān)控方式。
OpenTelemetry 的標(biāo)準(zhǔn)已經(jīng)被業(yè)界普遍使用,JMX 也可以和 OpenTelemetry 集成。用于 JMX 的 OpenTelemetry 集成利用 YAML 中指定的配置文件來描述應(yīng)用程序的指標(biāo)應(yīng)如何轉(zhuǎn)換為 OpenTelemetry 指標(biāo)。這些規(guī)則會提供給與 JMX API 交互的 JMX 指標(biāo)抓取工具。許多現(xiàn)有的 Java 應(yīng)用程序可配置為通過 JMX 發(fā)出指標(biāo)。以下應(yīng)用程序具有社區(qū)支持的預(yù)定義規(guī)則文件:
- Activemq
- Cassandra
- Hbase
- Hadoop
- Jetty
- Jvm
- Kafka
- Solr
- Tomcat
- Wildfly
這意味著,在使用 JMX 抓取工具時,可以將目標(biāo)應(yīng)用程序識別為上述選項(xiàng)之一,無需任何額外配置即可自動抓取指標(biāo)。
使用 OpenTelemetry 的 JMX 集成從應(yīng)用程序中提取數(shù)據(jù)有多種方法:
- 運(yùn)行 JMX 指標(biāo)收集器 JAR 并將其指向您的應(yīng)用程序
- 將 OpenTelemetry Java 代理與應(yīng)用程序一起運(yùn)行
- 運(yùn)行 OpenTelemetry Collector 并配置 JMX 接收器以通過 JMX 獲取指標(biāo)
JMX 指標(biāo)收集器是一種簡單便捷的方法,可用于測試從 Java 應(yīng)用程序?qū)С鲋笜?biāo),且所需的額外依賴最少。OpenTelemetry Java 代理是一種更成熟且經(jīng)過驗(yàn)證的機(jī)制,但由于它引入了額外的 instrumentation,可能也會帶來一些開銷。如果在你的環(huán)境中運(yùn)行單獨(dú)的進(jìn)程或工作負(fù)載是可接受的,那么 OpenTelemetry 收集器是一個可靠的替代方案。本文將探討這三種選擇。
配置
在深入了解 OpenTelemetry 集成之前,有必要確保將要測試的應(yīng)用程序正確暴露 JMX 端點(diǎn)。以下命令在 Docker 容器中啟動 Tomcat 服務(wù)器,以減少本地系統(tǒng)所需的依賴項(xiàng)數(shù)量。它使用 JAVA_OPTS 環(huán)境變量啟用 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
有許多工具可以驗(yàn)證 JMX 端口是否可訪問以及是否在生成指標(biāo)。以下使用 JConsole 并連接到已打開的端口:
$ jconsole localhost:9999
這將彈出一個應(yīng)用程序,它可能會提示您連接不安全。在本地開發(fā)時,此警告可以安全地忽略。

這些數(shù)據(jù)可通過遠(yuǎn)程 JMX 端口訪問,我們已準(zhǔn)備好與 OpenTelemetry 集成。
直接使用 JMX scraper
如前所述,JMX 抓取工具是最簡便的入門方式。以下命令將:
- 從 Maven 下載 JMX 抓取工具的最新發(fā)布版本
- 運(yùn)行 JMX 抓取工具,將其配置為從 Tomcat 收集遙測數(shù)據(jù),并通過 JMX 收集指標(biāo),然后將這些指標(biāo)輸出到本地控制臺。
$ 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
該命令的輸出讓我們知道連接已建立,并且一些度量工具已創(chuàng)建:
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抓取工具是個不錯的入門方法,但它確實(shí)需要一個額外的 JAR 包,如果我們已經(jīng)在使用 Java 代理,可能就不希望這樣了。
使用 OpenTelemetry Java 代理
除了提供 JMX 集成外,Java 代理還提供了自動檢測應(yīng)用程序的功能。出于這個原因,它比 JMX 抓取工具更常用。以下命令:
- 下載最新發(fā)布版本的 OpenTelemetry Java agent jar
- 通過將本地目錄掛載到容器中,將 jar 包歸檔文件添加到 Docker 環(huán)境中
- 使用一些額外的環(huán)境變量運(yùn)行與之前相同的 Tomcat 應(yīng)用程序,以加載 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
該命令的輸出將與運(yùn)行 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
如果我們的部署已經(jīng)在使用 OpenTelemetry Java 代理,現(xiàn)在我們就有了一種無需引入額外工具即可收集 JMX 指標(biāo)的方法。但如果我們更傾向于使用外部工具,那該怎么辦呢?別擔(dān)心,OpenTelemetry 這把“瑞士軍刀”已經(jīng)為你準(zhǔn)備好了!
使用 OpenTelemetry Collector 和 JMX receiver
我們將要探討的最后一種將JMX指標(biāo)轉(zhuǎn)換為 OpenTelemetry 的方法是使用 OpenTelemetry Collector。Collector 提供了許多集成功能,通常作為遙測管道的一部分部署在基礎(chǔ)設(shè)施內(nèi)部。Collector 由許多組件構(gòu)成,其中之一是 JMX receiver,它在底層使用 JMX scraper 與 Java 應(yīng)用程序進(jìn)行交互。
在本示例中,我們將繼續(xù)使用之前一直在用的 tomcat 應(yīng)用程序,并使用由社區(qū)發(fā)布和維護(hù)的 OpenTelemetry Collector Contrib 發(fā)行版。運(yùn)行帶有調(diào)試導(dǎo)出器的 Collector 需要以下配置文件,該調(diào)試導(dǎo)出器會將指標(biāo)輸出到控制臺。由于 Collector 便于配置多個導(dǎo)出器,我們還添加了一個 OpenTelemetry 協(xié)議(OTLP)導(dǎo)出器,用于將數(shù)據(jù)發(fā)送到 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 抓取器 JAR 的位置,因?yàn)榻邮掌鞅旧聿⒉话?JAR。有了這份配置,以下命令將下載最新發(fā)布的 Collector Contrib 發(fā)行版并運(yùn)行它:
$ 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
收集器的輸出將包含來自JMX抓取器的詳細(xì)信息以及來自調(diào)試導(dǎo)出器的日志,以驗(yàn)證數(shù)據(jù)是否按照配置進(jìn)行導(dǎo)出。
使用 Collector 使我們能夠收集指標(biāo),而無需修改應(yīng)用程序或應(yīng)用程序運(yùn)行的環(huán)境,只要該應(yīng)用程序遠(yuǎn)程暴露 JMX 端口即可。 Collector 還增加了一些靈活性,可以根據(jù)需要對數(shù)據(jù)進(jìn)行轉(zhuǎn)換或豐富。
自定義應(yīng)用的監(jiān)控采集
OpenTelemetry 社區(qū)支持的應(yīng)用程序列表不足以處理所有現(xiàn)有的Java應(yīng)用程序。幸運(yùn)的是,可以定義自定義規(guī)則配置文件來支持自定義應(yīng)用程序。該項(xiàng)目的官方文檔更詳細(xì)地描述了編寫自定義配置的語法。在下面的示例中,我們創(chuàng)建的規(guī)則為Resin服務(wù)器暴露的指標(biāo)提供了映射。此配置將resin命名空間中ThreadPool托管Bean(MBean)的JMX屬性ThreadActiveCount映射到OpenTelemetry中名為resin.threadpool.active.count的 gauge(量規(guī)):
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"
將OpenTelemetry與JMX集成的每種方法都支持自定義配置文件。JMX抓取器通過otel.jmx.config屬性來支持這一點(diǎn)。收集器中的JMX接收器可以使用jmx_configs而非target_system進(jìn)行配置。允許收集器使用此自定義文件的配置如下:
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
總結(jié)
有了這些,我們現(xiàn)在就具備了將生成JMX遙測數(shù)據(jù)的應(yīng)用程序集成到任何支持 OpenTelemetry 的遙測管道中的工具。可以靈活選擇使用JMX抓取器、Java代理或收集器,這確保我們能夠選用適合自身環(huán)境的工具,同時對現(xiàn)有工作流程的影響降至最低。

浙公網(wǎng)安備 33010602011771號