內容
筆者在阿里雲服務器中配置Java項目的JMX遠程連接,在確認JVM參數、防火牆、阿里雲安全組設置都無誤后,使用JConsole等工具連接JVM時仍出現JMX連接失敗的問題。筆者將該問題的解決方法記錄成文,供網友遇到同樣問題時能快速的處理。
版本
操作系統: CentOS 7.2 64位
JDK:1.8.0_181
說明
轉載請說明出處:Linux入門實踐筆記(七)——雲服務器中配置Java項目的JMX連接失敗問題解決記錄
JMX連接的官方文檔:https://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html
為何要開啟JMX監控
作為一名Java開發人員,大多數情況下,只要確保寫好的代碼功能能跑通即可,很少關注代碼對CPU、內存、線程的資源依賴情況。但是如果出現了Out-Of-Memory等問題,或想監控Java項目的運行狀況(比如在進行壓力測試時),可以使用JMX客戶端監控JVM的資源使用情況。常用的JMX客戶端有JConsole、JMC、JVisualVM,這些都是JDK自帶的工具。
開啟JVM的JMX監控
在啟動jar包時添加com.sun.management.jmxremote.* 相關的JVM參數,該示例以7199為JMX遠程監控的端口,不使用SSL安全連接,不啟用賬號密碼認證:
[user@ServerA2 jars]$ java -Dcom.sun.management.jmxremote.port=7199 #供JMX客戶端遠程連接用的端口號
-Dcom.sun.management.jmxremote.authenticate=false #關閉賬號密碼認證,不安全,僅在開發階段使用
-Dcom.sun.management.jmxremote.ssl=false #關閉SSL
-Djava.rmi.server.hostname=106.117.142.x #指定本機供遠程訪問的IP地址,此處是本機的公網IP
-Xms512m -Xmx512m -jar zuul-1.0-SNAPSHOT.jar &
其中-Djava.rmi.server.hostname參數一定要設置,否則連接失敗。
雲服務器JMX連接失敗原因
正確地配置了JVM參數后啟動jar包,在本地仍然無法使用JMX Client訪問雲服務器上的JVM。筆者在阿里雲提交了工單,經過長達兩天時間多次溝通后終於得知JMX連接失敗的原因。
開啟JMX遠程監控管理功能后,JVM不僅會占用指定的com.sun.management.jmxremote.port配置的端口號7199,還會額外再開啟兩個隨機的端口號用於通信。如果這兩個隨機的端口號沒有開放訪問,那么遠程JVM Client還是無法連接到JVM的。
執行netstat -nltp
命令可以查看JVM進程監聽的端口,本示例中啟動的java進程的PID為15703,通過下面的查詢可知需要額外放行的兩個端口為41264和41665。
[user1@ServerA2 jars]$ netstat -nltp #其中:-n表示表示輸出中不顯示主機,端口和用戶名,-lb表示只顯示監聽listening端口,-t表示只顯示tcp協議的端口,-p表示顯示進程的PID和進程名稱。
(Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:41264 0.0.0.0:* LISTEN 15703/java tcp 0 0 0.0.0.0:8881 0.0.0.0:* LISTEN 15703/java tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:7001 0.0.0.0:* LISTEN 15074/java tcp 0 0 0.0.0.0:7101 0.0.0.0:* LISTEN 15074/java tcp 0 0 0.0.0.0:7199 0.0.0.0:* LISTEN 15703/java tcp 0 0 127.0.0.1:32000 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:41665 0.0.0.0:* LISTEN 15703/java tcp6 0 0 :::80 :::* LISTEN -
將這兩個端口號在安全組中放行后,遠程JMX Client就可以正常訪問JVM,真坑。