1. 程式人生 > >基於JVisualVM的可視化監控

基於JVisualVM的可視化監控

目錄 能夠 線上 tex moni 方便 man 系統屬性 ans

監控本地的java進程

本小節我們介紹一下如何使用JDK自帶的jvisualvm工具來監控本地的Java進程,該工具是一個圖形化的監控工具。

jvisualvm官方文檔地址如下:

https://visualvm.github.io/documentation.html

一、介紹

VisualVM,能夠監控線程,內存情況,查看方法的CPU時間和內存中的對 象,已被GC的對象,反向查看分配的堆棧(如100個String對象分別由哪幾個對象分配出來的).

從界面上看還是比較簡潔的,左邊是樹形結構,自動顯示當前本機所運行的Java程序,還可以添加遠程的Java VM,其中括號裏面的PID指的是進程ID。OverView界面顯示VM啟動參數以及該VM對應的一些屬性。Monitor界面則是監控Java堆大小,Permgen大小,Classes和線程數量。jdk不同版本中界面會不太一致,如有的含cpu監控,有的則不含(jdk1.6.0_10未包含)。

二、JVisualVM能做什麽

VisualVM 是Netbeans的profile子項目,已在JDK6.0 update 7 中自帶,能夠監控線程,內存情況,查看方法的CPU時間和內存中的對 象,已被GC的對象,反向查看分配的堆棧(如100個String對象分別由哪幾個對象分配出來的)。

三、jvisualvm在哪

jvisualvm位於JAVA_HOME/bin目錄下,如下圖:
技術分享圖片

直接雙擊就可以打開該程序,打開後界面如下:
技術分享圖片

如果只是監控本地的java進程,是不需要配置參數的,直接打開就能夠進行監控。首先我們需要在本地打開一個Java程序,例如我打開IDEA,這時在jvisualvm界面就可以看到與IDEA相關的Java進程了:

技術分享圖片

點擊一個進程,就可以看到該進程的概述信息,該進程的JVM參數以及系統屬性等信息都能夠查看到:
技術分享圖片

點擊 “監視” 就能夠看到CPU、內存、類以及線程的活動狀況,點擊右上角的 “堆Dump” 就能夠導出內存映像文件:
技術分享圖片

除了導出,也還可以導入內存映像文件,只不過分析功能上沒有MAT強大:
技術分享圖片

點擊 “線程” 就能夠看到該進程內部的所有線程,以及線程的運行狀況等信息。如果點擊右上角的 “線程Dump” 就會導出一個內容與jstack打印內容一致的文件:
技術分享圖片

點擊 “抽樣器” 界面中的 “CPU ” 就可以動態的看到每個方法的執行時間,當我們的代碼執行的比較慢了,就可以通過抽樣器來查看是哪一個方法執行的比較慢:

技術分享圖片

而點擊 “內存” 的話,就可以實時的、動態的查看到每個類實例對象的數量以及這些實例所占用的內存大小:
技術分享圖片

在Profiler界面上,可以對CPU、內存進行性能分析,分析後會給出分析結果:
技術分享圖片

接下來我們下載兩個比較實用的插件,首先到VisualVM插件中心,地址如下:

https://visualvm.github.io/pluginscenters.html

因為有時候自帶的插件地址可能無法使用,所以我們需要自行配置可用的地址:
技術分享圖片

回到jvisualvm中,點擊菜單欄中的 “工具“ 選項,再點擊子菜單的 ”插件“ 選項:
技術分享圖片

然後按照下圖配置插件地址:
技術分享圖片

配置好插件地址後,按照下圖勾選以下兩個插件:
技術分享圖片

按照提示一步步的進行安裝:
技術分享圖片
技術分享圖片

安裝完成:
技術分享圖片

插件安裝完成後需要重啟jvisualvm才會生效,這時會看到選項卡中多了一個 “Visual GC” 選項,點擊該選項後,可以動態的查看到JVM內存結構各個區域的運行狀況,極大方便我們進行各個區內存的監控及調優:
技術分享圖片

另一個插件的作用就是可以讓我們針對某個進程編寫BTrace腳本,右鍵點擊一個進程,在彈出來的菜單中,選擇“Trace application...”,就可以編寫BTrace腳本了:
技術分享圖片


監控遠程的java進程

在上一小節中,我們簡單介紹了如何使用JDK自帶的jvisualvm工具來監控本地的Java進程。而本小節我們將介紹一下如何使用jvisualvm來監控遠程的java進程,我們這裏以線上服務器的Tomcat為例。

打開jvisualvm,雙擊 “遠程” 選項,添加一個遠程主機,即遠程的服務器:
技術分享圖片

然後編輯Tomcat的catalina.sh文件,在該文件中加入如下配置內容:

[root@server ~]# vim /home/tomcat/apache-tomcat-8.5.8/bin/catalina.sh
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9004 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.net.preferIPv4Stack=true -Djava.rmi.server.hostname=119.23.250.83"

配置簡單說明:

  • -Dcom.sun.management.jmxremote添加一個jmx遠程連接屬性
  • -Dcom.sun.management.jmxremote.port=9004 指定連接的端口號
  • -Dcom.sun.management.jmxremote.authenticate=false 是否啟用驗證
  • -Dcom.sun.management.jmxremote.ssl=false 是否啟用ssl
  • Djava.net.preferIPv4Stack=true 是否優先使用ipv4
  • -Djava.rmi.server.hostname=119.23.250.83 指定遠程主機的ip地址

如下圖:
技術分享圖片

增加完配置後,重啟Tomcat,查看是否有9004端口,有的話就代表配置成功了,如下:

[root@server ~]# netstat -lntp |grep java
tcp        0      0 0.0.0.0:9004            0.0.0.0:*               LISTEN      13399/java          
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      13399/java          
tcp        0      0 0.0.0.0:46199           0.0.0.0:*               LISTEN      13399/java          
tcp        0      0 0.0.0.0:32859           0.0.0.0:*               LISTEN      13399/java          
tcp        0      0 127.0.0.1:8005          0.0.0.0:*               LISTEN      13399/java          
tcp        0      0 0.0.0.0:8009            0.0.0.0:*               LISTEN      13399/java          
[root@server ~]#

回到jvisualvm中,添加JMX連接,配置連接地址和端口,如下:
技術分享圖片
技術分享圖片

註意,如果你使用的是阿裏雲等雲服務器的話,不僅需要配置防火墻規則來開放端口,還需要到雲服務器的安全組規則中,增加相應的端口規則,如下:
技術分享圖片

連接成功後,如下:
技術分享圖片

同樣的,可以像監控本地進程一樣,監控遠程的進程,在界面的操作上是一模一樣的。唯一不同的也就是需要添加一個遠程主機,然後到遠程的Java進程上配置一些jmx參數而已:
技術分享圖片

以上我們是以Tomcat這種服務型的進程作為一個示例,只需要去配置Tomcat的腳本文件就可以了。那麽如果我們需要監控的是自己線上跑的一個Java進程需要怎麽進行配置呢?其實也是一樣的,同樣的是使用這些參數,只不過是作為啟動參數而已,在啟動項目的時候加上即可,如下:

[root@server ~]# nohup java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9005 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.net.preferIPv4Stack=true -Djava.rmi.server.hostname=119.23.250.83 -jar monitor_tuning-0.0.1-SNAPSHOT.jar &

成功啟動後,也是使用同樣的方式進行連接,註意端口不要弄錯了:
技術分享圖片

連接成功後也是一樣的:
技術分享圖片

然後我們就可以愉快的在本地監控遠程的Java進程了,而且還是圖形化的,免去了敲命令的煩惱。

我們來做一個堆內存溢出的實驗,看看jvisualvm能否監控到內存的變化,在瀏覽器上訪問我們之前在基於JDK命令行工具的監控一文中所編寫的/head接口。訪問後如下,可以看到堆內存的變化很激烈,利用jvisualvm工具進行監控,就很明顯的就能夠觀察到該進程的異常:
技術分享圖片

所以線上監控不能少,是我們必須要掌握的一種技能。監控相當於我們的眼睛,如果沒有監控工具,那我們就相當於瞎子一樣兩眼一抹黑。無法看到內存、線程的使用情況,當出現異常的時候,也難以定位問題發生的原因。

基於JVisualVM的可視化監控