JVM 默認(rèn)會(huì)通過(guò) JMX 的方式暴露基礎(chǔ)指標(biāo),很多中間件也會(huì)通過(guò) JMX 的方式暴露業(yè)務(wù)指標(biāo),比如 Kafka、Zookeeper、ActiveMQ、Cassandra、Spark、Tomcat、Flink 等等。掌握了 JMX 監(jiān)控方式,就掌握了一批程序的監(jiān)控方式。本節(jié)介紹 JMX-Exporter 的使用,利用 JMX-Exporter 把 JMX 監(jiān)控?cái)?shù)據(jù)暴露為 Prometheus 可識(shí)別的格式。
JMXJMX(Java Management Extensions)是 Java 管理擴(kuò)展的簡(jiǎn)稱(chēng),是一種為 Java 應(yīng)用程序植入管理功能的框架。Java 類(lèi)程序經(jīng)常使用 JMX 暴露監(jiān)控指標(biāo)數(shù)據(jù),也可以通過(guò) JMX 來(lái)控制 Java 類(lèi)程序,典型的比如通過(guò) JMX 觸發(fā)程序 GC。
Java 程序里,某個(gè)類(lèi)如果實(shí)現(xiàn)了 MBean 接口,那么這個(gè)類(lèi)就可以通過(guò) JMX 來(lái)讀取和修改這個(gè)類(lèi)的屬性,也可以調(diào)用這個(gè)類(lèi)的方法。JMX 通過(guò) MBeanServer 來(lái)管理 MBean,MBeanServer 是一個(gè)管理器,它可以管理多個(gè) MBean,每個(gè) MBean 都有一個(gè) ObjectName,用來(lái)唯一標(biāo)識(shí)這個(gè) MBean。
(資料圖片僅供參考)
更新信息可以參考JMX Specification。非本文重點(diǎn)。
JMX-Exporter簡(jiǎn)介JMX-Exporter 是 Prometheus 社區(qū)提供的一個(gè)工具,用來(lái)把 JMX 暴露的監(jiān)控指標(biāo)數(shù)據(jù)轉(zhuǎn)換為 Prometheus 可識(shí)別的格式。JMX-Exporter 通過(guò) HTTP 服務(wù)的方式暴露監(jiān)控指標(biāo)數(shù)據(jù),Prometheus 通過(guò) HTTP 協(xié)議來(lái)拉取監(jiān)控指標(biāo)數(shù)據(jù)。
JMX-Exporter 就是個(gè) jar 包,以 javaagent(何為 javaagent,需要讀者自行 Google) 的方式運(yùn)行,和業(yè)務(wù) Java(或 Scala) 程序運(yùn)行在一個(gè) JVM 虛擬機(jī)里。有了 JMX-Exporter,業(yè)務(wù)程序無(wú)需暴露 JMX 端口了,JMX-Exporter 會(huì)把 JMX 暴露的監(jiān)控指標(biāo)數(shù)據(jù)轉(zhuǎn)換為 Prometheus 可識(shí)別的格式,然后通過(guò) HTTP 只讀方式暴露出去,也更為安全。
JMX-Exporter 安裝因?yàn)?JMX-Exporter 是個(gè) jar 包,所以安裝非常簡(jiǎn)單,只需要把 jar 包下載到服務(wù)器上就可以了。JMX-Exporter 的下載地址是https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/,下載最新版本的 jar 包即可。
比如我們把下載的 jar 包放在/opt/jmx-exporter目錄,另外,建立/etc/jmx-exporter目錄放置 JMX-Exporter 所需配置文件。像 Kafka,暴露的 JMX 指標(biāo)非常非常多,我們不需要全部采集,只需要采集我們關(guān)心的指標(biāo)即可。所以,我們需要配置文件來(lái)告訴 JMX-Exporter,我們需要采集哪些指標(biāo)。
JMX-Exporter 提供了很多樣例配置,地址在這里:https://github.com/prometheus/jmx_exporter/tree/main/example_configs。
使用 JMX 監(jiān)控 Zookeeper實(shí)際上,新版 Zookeeper 已經(jīng)直接暴露了 Prometheus 協(xié)議的監(jiān)控?cái)?shù)據(jù),無(wú)需通過(guò) JMX 方式采集了。另外,Zookeeper 還提供了四字命令的監(jiān)控?cái)?shù)據(jù)采集方式,比如 Categraf 的input.zookeeper插件就是采用的這種方式。
不過(guò),本文主要是演示 JMX 的方式,所以還是使用 JMX 的方式來(lái)采集 Zookeeper 的監(jiān)控?cái)?shù)據(jù)。
首先,從https://github.com/prometheus/jmx_exporter/tree/main/example_configs這里找到 Zookeeper 的配置樣例文件,下載到/etc/jmx-exporter/zookeeper.yml。然后把 jmx-exporter 的 jar 包作為 javaagent 啟動(dòng)參數(shù)加入 Zookeeper 的啟動(dòng)命令即可。
# zookeeper-env.shSERVER_JVMFLAGS="-javaagent:/opt/jmx-exporter/jmx-exporter.jar=7070:/etc/jmx-exporter/zookeeper.yml"
Zookeeper 有個(gè) zookeeper-env.sh 控制 Zookeeper 的啟動(dòng)參數(shù),我們?cè)谶@里加入 javaagent 啟動(dòng)參數(shù),然后重啟 Zookeeper 即可。上例是把 JMX-Exporter 的 HTTP 服務(wù)端口設(shè)置為 7070,可以根據(jù)實(shí)際情況修改,配置文件指定為/etc/jmx-exporter/zookeeper.yml。
OK,現(xiàn)在可以測(cè)試了,先看 7070 端口是否在監(jiān)聽(tīng),如果在監(jiān)聽(tīng),就可以請(qǐng)求這個(gè)端口的/metrics接口采集 Prometheus 協(xié)議的監(jiān)控?cái)?shù)據(jù)了。
$ netstat -tlnp | grep 7070tcp 0 0 0.0.0.0:7070 0.0.0.0:* LISTEN 892/java$ curl -s localhost:7070/metrics | head# HELP jvm_threads_current Current thread count of a JVM# TYPE jvm_threads_current gaugejvm_threads_current 16.0# HELP jvm_threads_daemon Daemon thread count of a JVM# TYPE jvm_threads_daemon gaugejvm_threads_daemon 12.0# HELP jvm_threads_peak Peak thread count of a JVM# TYPE jvm_threads_peak gaugejvm_threads_peak 16.0# HELP jvm_threads_started_total Started thread count of a JVM
可以看到,Zookeeper 的監(jiān)控?cái)?shù)據(jù)已經(jīng)暴露出來(lái)了,接下來(lái)就可以采集這些數(shù)據(jù)了,抓取 Prometheus 協(xié)議的監(jiān)控?cái)?shù)據(jù)有很多方式,可以直接使用 Prometheus 自身來(lái)抓取,也可以通過(guò) Categraf 的 input.prometheus 插件來(lái)抓取,也可以通過(guò) vmagent 來(lái)抓取,大家自行決策即可。
使用 JMX 監(jiān)控 Kafka從 JMX-Exporter 提供的樣例配置目錄,下載 kafka.yml,然后導(dǎo)出 KAFKA_OPTS 環(huán)境變量即可。
$ export KAFKA_OPTS="-javaagent:/opt/jmx-exporter/jmx-exporter.jar=7071:/etc/jmx-exporter/kafka.yml"$ /opt/kafka_2.11-0.10.1.0/bin/kafka-server-start.sh /opt/kafka_2.11-0.10.1.0/conf/server.properties
上例中,我們把端口換成了7071,配置文件指定為/etc/jmx-exporter/kafka.yml。測(cè)試一下端口是否成功監(jiān)聽(tīng):
$ netstap -tlnp | grep 7071tcp6 0 0 :::7071 :::* LISTEN 19288/java$ curl -s localhost:7071 | grep -i kafka | head# HELP kafka_server_replicafetchermanager_minfetchrate Attribute exposed for management (kafka.server
一切正常哈,如果你的 Kafka 是通過(guò) systemd 運(yùn)行的,可以類(lèi)似下面的方式來(lái)配置 kafka.service 文件:
...[Service]Restart=on-failureEnvironment=KAFKA_OPTS=-javaagent:/opt/jmx-exporter/jmx-exporter.jar=7071:/etc/jmx-exporter/kafka.ymlExecStart=/opt/kafka/bin/kafka-server-start.sh /etc/kafka/server.propertiesExecStop=/opt/kafka/bin/kafka-server-stop.shTimeoutStopSec=600User=kafka...加餐
使用 jmx-exporter jar 包的時(shí)候,會(huì)引用一個(gè)配置文件,不同的 Java 應(yīng)用可能會(huì)通過(guò) jmx 的方式暴露特別多的監(jiān)控指標(biāo),顯然,我們不需要采集所有,具體要采集哪些指標(biāo),就是靠 jmx-exporter jar 包引用的那個(gè)配置文件決定的。我們來(lái)看一下/etc/jmx-exporter/zookeeper.yml的內(nèi)容:
rules: # replicated Zookeeper - pattern: "org.apache.ZooKeeperService
這個(gè)配置文件里定義了一堆 rules,每個(gè) rule 由四部分組成:pattern、name、type、labels,其中 pattern 是一個(gè)正則表達(dá)式,用來(lái)匹配 MBean 的 object name(什么是 MBean,什么是 object name 可以自行 Google,這里暫不展開(kāi)),如果匹配到了就采集對(duì)應(yīng)的 MBean 的數(shù)據(jù),否則就不采集。type 是指定了數(shù)據(jù)類(lèi)型,labels 是指定了標(biāo)簽,標(biāo)簽值是來(lái)自 pattern 中提取到的正則數(shù)據(jù)。
所以,jmx 監(jiān)控?cái)?shù)據(jù)采集的關(guān)鍵點(diǎn),其實(shí)是這個(gè) rules 的最佳實(shí)踐,也就是說(shuō),對(duì)于某個(gè) Java 應(yīng)用,你具體要采集哪些指標(biāo),這是真經(jīng)驗(yàn),真正有價(jià)值的東西。
文章主要翻譯了https://alex.dzyoba.com/blog/jmx-exporter/并加入了一些個(gè)人理解。enjoy…make a better world :)
標(biāo)簽: