什么是 JMX?(Trino JMX 實戰講解)
一、概述
JMX 是 Java Management Extensions(Java管理擴展) 的縮寫,它是 Java 平臺上用于管理和監控應用程序、系統和網絡資源的一種標準化的管理和監控框架。JMX 提供了一種標準的方式,通過這種方式,開發人員可以暴露應用程序中的各種管理和監控信息,然后可以使用 JMX 客戶端工具或應用程序來訪問和操作這些信息。
JMX 允許開發人員定義稱為 MBeans(Managed Beans)的管理組件,這些組件充當被管理資源的代理,并通過 JMX 接口公開資源的操作和屬性。通過 MBeans,您可以監控和管理各種 Java 應用程序和服務器的性能、狀態和配置。
JMX 主要用于以下一些方面:
- 監控:可以使用 JMX 來監視應用程序的性能指標,例如內存使用、線程數、請求處理速度等。這對于實時性能分析和故障排除非常有幫助。
- 管理:JMX 允許您在運行時管理應用程序,例如修改配置參數、重新加載資源、觸發操作等。這有助于實現動態管理和配置。
- 遠程管理:JMX 支持遠程訪問,這意味著您可以在不必物理接觸應用程序的情況下,從遠程位置監控和管理應用程序。
- 自定義監控:您可以編寫自定義 MBeans 來公開特定于您的應用程序的監控數據和操作,以滿足特定的管理需求。
總之,JMX 提供了一個強大的框架,用于管理和監控 Java 應用程序,這對于確保應用程序的穩定性和性能至關重要。它廣泛用于企業級應用程序和服務器,如應用程序服務器、數據庫服務器和中間件。
二、JMX 原理
圖片
從圖中我們可以看到,JMX的結構一共分為三層:
- 基礎層:主要是 MBean,被管理的資源。
MBean 分為如下四種,我接下來主要介紹 standard MBean
類型 | 描述 |
standard MBean | 這種類型的MBean最簡單,它能管理的資源(包括屬性,方法,時間)必須定義在接口中,然后MBean必須實現這個接口。它的命名也必須遵循一定的規范,例如我們的MBean為Hello,則接口必須為HelloMBean。 |
dynamic MBean | 必須實現javax.management.DynamicMBean接口,所有的屬性,方法都在運行時定義 |
open MBean | 此MBean的規范還不完善,正在改進中 |
model MBean | 與標準和動態MBean相比,你可以不用寫MBean類,只需使用javax.management.modelmbean.RequiredModelMBean即可。RequiredModelMBean實現了ModelMBean接口,而ModelMBean擴展了DynamicMBean接口,因此與DynamicMBean相似,Model MBean的管理資源也是在運行時定義的。與DynamicMBean不同的是,DynamicMBean管理的資源一般定義在DynamicMBean中(運行時才決定管理那些資源),而model MBean管理的資源并不在MBean中,而是在外部(通常是一個類),只有在運行時,才通過set方法將其加入到model MBean中。后面的例子會有詳細介紹 |
- 適配層:MBeanServer,主要是提供對資源的注冊和管理。
- 接入層:提供遠程訪問的入口。
三、實戰操作(開啟 Trino JMX)
1)環境部署
Trino官方文檔:https://trino.io/docs/current/
這里為了快速部署就選擇docke-compose部署了。
git clone https://gitee.com/hadoop-bigdata/docker-compose-presto.git
cd docker-compose-presto
# 啟動服務
docker-compose -f docker-compose.yaml up -d
# 查看
docker-compose -f docker-compose.yaml ps
2)開啟 Trino JMX
官方文檔:https://trino.io/docs/current/admin/jmx.html
1、配置 config.properties
jmx.rmiregistry.port=9080
jmx.rmiserver.port=9081
參數解釋:
- jmx.rmiregistry.port:指定jmx RMI注冊表的端口。JMX客戶端應該連接到此端口。
- jmx.rmiserver.port:指定jmx RMI服務器的端口。Trino導出許多指標,這些指標對于通過JMX進行監控非常有用。
2、配置 jvm.config
-Dcom.sun.management.jmxremote.rmi.port=9081
jmx.rmiregistry.port、jmx.rmiserver.port 和 -Dcom.sun.management.jmxremote.rmi.port 這三者都涉及到 Java Management Extensions (JMX)和遠程管理的端口配置,但它們各自在不同的上下文中起作用:
- jmx.rmiregistry.port:這個屬性指定了 RMI(Remote Method Invocation:遠程方法調用) 注冊表(RMI Registry)的端口號。RMI 注冊表用于注冊 JMX 服務,以便客戶端可以查找并連接到 JMX 服務。通常情況下,RMI 注冊表使用默認端口號 1099。通過設置 jmx.rmiregistry.port 屬性,你可以指定 RMI 注冊表使用的不同端口號,以防止端口沖突或增加安全性。
- jmx.rmiserver.port:這個屬性指定了 JMX 服務本身的 RMI 通信端口號。JMX 服務使用 RMI 進行遠程通信,客戶端通過這個端口與 JMX 服務通信。通常情況下,JMX 服務也使用默認的端口號 1099。通過設置 jmx.rmiserver.port 屬性,你可以指定 JMX 服務的 RMI 端口號。
- -Dcom.sun.management.jmxremote.rmi.port:這是 Java 系統屬性,用于配置 JMX 遠程連接的 RMI 端口號。它指定了客戶端將用來連接到 JMX 服務的 RMI 端口號。通常情況下,如果不顯式設置,它會使用與 jmx.rmiserver.port 相同的端口號。但你也可以使用這個系統屬性來指定不同的端口號,以確??蛻舳丝梢赃B接到正確的端口。
這三者之間的關系是:
jmx.rmiregistry.port 和 jmx.rmiserver.port 分別指定 RMI 注冊表和 JMX 服務的端口號。-Dcom.sun.management.jmxremote.rmi.port 可以用來指定客戶端連接到 JMX 服務時所使用的 RMI 端口號,它通常設置為與 jmx.rmiserver.port 相同的端口號,但你也可以根據需要將其設置為不同的端口號。
3、重新啟動服務
docker-compose -f docker-compose.yaml up -d
docker-compose -f docker-compose.yaml ps
4、獲取監控數據
curl -s -H "X-Trino-User:admin" http://192.168.182.110:30080/v1/jmx/mbean
圖片
通過jmx 接口就可以獲取監控數據了/v1/jmx/mbean,但是數據很多,其實我們可以拿一些我們需要的指標數據即可。接下來我們通過jq 拿到各項監控的子接口。jq 命令的使用可以參考我這篇文章:Linux jq 命令講解與實戰操作(json字符串解析工具)
# coodinator
curl -s -H "X-Trino-User:admin" http://192.168.182.110:30080/v1/jmx/mbean|jq '.[].objectName'
圖片
訪問具體接口指標
# 內存指標接口
curl -s -H "X-Trino-User:admin" http://192.168.182.110:30080/v1/jmx/mbean|jq '.[].objectName'|grep -i memory
# 指標名稱
curl -s -H "X-Trino-User:admin" http://192.168.182.110:30080/v1/jmx/mbean/java.lang:type=Memory|jq '.attributes[].name'
# 指標值
curl -s -H "X-Trino-User:admin" http://192.168.182.110:30080/v1/jmx/mbean/java.lang:type=Memory|jq '.attributes[].value'
# 指標名稱
curl -s -H "X-Trino-User:admin" http://192.168.182.110:30080/v1/jmx/mbean/trino.memory:type=MemoryPool,name=general|jq '.attributes[].name'
# 指標值
curl -s -H "X-Trino-User:admin" http://192.168.182.110:30080/v1/jmx/mbean/trino.memory:type=MemoryPool,name=general|jq '.attributes[].value'
圖片
# worker 節點,coodinator與worker節點的指標會有些不一樣
curl -s -H "X-Trino-User:admin" http://192.168.182.110:49153/v1/jmx/mbean|jq '.[].objectName'
# 獲取內存接口
curl -s -H "X-Trino-User:admin" http://192.168.182.110:49153/v1/jmx/mbean|jq '.[].objectName'|grep -i memory
# 指標名稱
curl -s -H "X-Trino-User:admin" http://192.168.182.110:30080/v1/jmx/mbean/trino.memory:type=MemoryPool,name=general|jq '.attributes[].name'
# 指標值
curl -s -H "X-Trino-User:admin" http://192.168.182.110:30080/v1/jmx/mbean/trino.memory:type=MemoryPool,name=general|jq '.attributes[].value'
圖片
3)通過 jconsole 連接 JMX
JConsole 是一個基于JMX的GUI工具,用于連接正在運行的JVM,不過此JVM需要使用可管理的模式啟動。如果要把一個應用以可管理的形式啟動,可以在啟動是設置 com.sun.management.jmxremote。
找到java安裝bin目錄,目錄下有個jconsole可執行文件,雙擊點擊打開。
圖片
也可以通過 VisualVM 連接 JMX 查看數據
圖片
4)常用的 Trino 指標接口和指標
查詢所有jmx子接口:
curl -s -H "X-Trino-User:admin" http://192.168.182.110:30080/v1/jmx/mbean|jq '.[].objectName'
# 查詢指標名稱和值,示例如下:
# 指標名稱
curl -s -H "X-Trino-User:admin" http://192.168.182.110:30080/v1/jmx/mbean/java.lang:type=Memory|jq '.attributes[].name'
# 指標值
curl -s -H "X-Trino-User:admin" http://192.168.182.110:30080/v1/jmx/mbean/java.lang:type=Memory|jq '.attributes[].value'
以下就是常用的指標接口和指標說明:
指標接口 | 指標 | 說明 | 指標范圍 |
java.lang:type=Memory | HeapMemoryUsage | JVM內存使用量。 | Worker 和 Coodinator |
java.lang:type=Memory | NonHeapMemoryUsage | 非堆內存使用量。 | worker 和 Coodinator |
trino.execution:name=QueryManager | QueuedQueries | 排隊數 | Coodinator |
trino.execution:name=QueryManager | RunningQueries | 正在運行的查詢總數 | Coodinator |
trino.execution:name=QueryManager | ExternalFailures.OneMinute.Count | 每分鐘外部異常導致的失敗查詢數。 | Coodinator |
trino.execution:name=QueryManager | SubmittedQueries.OneMinute.Count | 每分鐘提交的查詢總數。 | Coodinator |
trino.execution:name=QueryManager | CanceledQueries.OneMinute.Count | 已取消查詢的數。 | Coodinator |
trino.execution:name=QueryManager | InsufficientResourcesFailures.OneMinute.Count | 每分鐘資源不足導致的失敗查詢數。 | Coodinator |
trino.execution:name=QueryManager | UserErrorFailures.OneMinute.Count | 每分鐘異常導致的失敗查詢數。 | Coodinator |
trino.execution:name=QueryManager | CompletedQueries.OneMinute.Count | 已完成查詢的總數。 | Coodinator |
trino.execution:name=SqlTaskManager | FailedTasks.OneMinute.Count | 每分鐘失敗的Task數目。 | Coodinator |
trino.execution:name=SqlTaskManager | InputDataSize.OneMinute.Count | 每分鐘Task輸入數據量。 | Coodinator |
trino.execution:name=SqlTaskManager | InputPositions.OneMinute.Count | 每分鐘Task輸入數據行數。 | Coodinator |
trino.execution:name=SqlTaskManager | OutputDataSize.OneMinute.Count | 每分鐘Task輸出數據量。 | Coodinator |
trino.execution:name=SqlTaskManager | OutputPositions.OneMinute.Count | 每分鐘Task輸出數據行數。 | Coodinator |
trino.memory:type=MemoryPool,name=general | FreeBytes | 節點內存池可用內存。 | worker 和 Coodinator |
trino.memory:type=MemoryPool,name=general | MaxBytes | 節點內存池最大內存(JVM*70%)。 | worker 和 Coodinator |
trino.memory:type=MemoryPool,name=general | ReservedBytes | 節點內存池reserved內存。 | worker 和 Coodinator |
trino.memory:type=MemoryPool,name=general | ReservedRevocableBytes | 節點內存池revocable reserved內存。 | worker 和 Coodinator |
trino.memory:type=ClusterMemoryPool,name=general | ReservedRevocableDistributedBytes | 集群內存池revocable reserved內存。 | Coodinator |
trino.memory:name=ClusterMemoryManager | QueriesKilledDueToOutOfMemory | oom killed的查詢總數。 | Coodinator |
trino.memory:type=ClusterMemoryPool,name=general | TotalDistributedBytes | 集群內存池總內存。 | Coodinator |
trino.memory:type=ClusterMemoryPool,name=general | ReservedDistributedBytes | 集群內存池reserved內存。 | Coodinator |
trino.memory:name=ClusterMemoryManager | ClusterUserMemoryReservation | 集群reserved user memory。 | Coodinator |
trino.memory:name=ClusterMemoryManager | ClusterTotalMemoryReservation | 集群reserved內存。 | Coodinator |
trino.memory:name=ClusterMemoryManager | NumberOfLeakedQueries | 集群內存泄漏的查詢總數。 | Coodinator |
trino.memory:name=ClusterMemoryManager | ClusterMemoryBytes | 集群總內存。 | Coodinator |
trino.execution.executor:name=TaskExecutor | WaitingSplits | 任務執行器上等待的splits數。 | Coodinator |
trino.execution.executor:name=TaskExecutor | RunningSplits | 任務執行器運行的splits數。 | Coodinator |
trino.execution.executor:name=TaskExecutor | RunningSplits | 任務執行器總splits數。 | Coodinator |
上面只是開啟了 Trino JMX,指標數據也采集了,怎么展示呢?下一篇文章重點講解通過 JMX-Exporter 采集數據,然后通過 Prometheus 拉取JMX采集的數據,最后通過Grafana展示。