1. 程式人生 > 程式設計 >java應用監測(1)-java程式設計師應該知道的應用監測技術

java應用監測(1)-java程式設計師應該知道的應用監測技術

tags: java,troubleshooting,monitor


一句話概括:java應用監測,為什麼?監測什麼?如何監測?本文為你解答。

1 引言:為什麼需要監測java應用

java開發人員都知道,啟動java應用使用的是java(class檔案)或java -jar(jarwar包)命令。而java命令其實就是啟動一個java虛擬機器器(JVM),程式就是執行在JVM上,JVM負責類載入,執行時區域堆疊分配等工作,而堆疊分別用於程式中的物件及執行緒使用,分別影響的系統的cpu及記憶體,如果程式涉及檔案或資料讀寫,還會影響系統的IO。因此,一個java應用啟動後,如果不對它所佔用的資源情況進行監測,無疑於一架飛機起飛了,卻沒有儀表盤,這種飛機估計沒有人敢坐。因此,作為開發人員,得清楚應用啟動後的執行情況,並能夠對應用執行狀況進行監測,如此,才能及時預測有可能發生的問題進行及時修正或發生問題後可以更快,更好地找到原因所在,進而解決。可喜的是,程式本身,java工具和第三方工具,都為我們提供了很多監測java應用的方法,因此,作為java開發人員,有必要對它們做一個系統的瞭解,以便於在實際應用中(特別是在生產環境中)更從容,更有效率的處理問題。

2 監測什麼

一個java應用執行起來,若出現問題,我們第一反應肯定是檢視日誌,檢視一下具體是報什麼錯,若沒有報錯,只是執行很慢,或者只是暫時還沒有報錯,那我們需要監測什麼內容呢?這一節,對比我們平時使用作業系統,來看看對於java應用,需要監測什麼內容。

2.1 系統監測內容

對於我們平時使用的作業系統,如windowslinux系統,出現應用開啟緩慢,系統響應緩慢,一般就是先檢視系統的cpu執行和記憶體使用情況,找出佔用資源高的程式,定位原因,在windows,直接在工作管理員-->效能中檢視,如下圖。

linux,可以使用top,free,df,iostat等命令進行檢視,如下圖。

在日常的運維過程中,也是對系統的磁碟使用、IO、CPU、記憶體、網路等情況進行監測,爭取及時發現佔用資源高的程式,定位問題然後處理。

2.2 java應用監測內容

相對於作業系統,java應用需要監測的內容也有類似的地方,如佔用的cpu情況,記憶體情況,其中,會包含java應用的JVM引數,堆佔用情況,執行緒執行狀態,類載入情況,垃圾回收(GC)情況。至於為什麼需要監測這些內容,就需要對java的虛擬機器器(JVM)有一定的瞭解,由於本文JVM涉及內容較多,後面有機會再對JVM進行詳細講解,這裡可以對java的JVM體系作一個簡要介紹,以便於讀者對後面章節的理解。見下圖:

  • 當java執行一個應用,就會生成一個JVM的例項,而java應用則執行於此JVM例項中,當應用退出,JVM例項也會關閉。啟動多個java應用,也會啟動多個JVM例項,它們不會相互影響(當然,它們都會佔用系統的資源)。

  • 虛擬機器器主要有三大模組,一個類載入子系統(Class Loader Subsystem,負責載入類),一個執行引擎(Execution Engine,負責執行類的方法指令和垃圾回收),一個執行時資料區(Runtime Data Areas,負責存放程式執行時的資料)。

  • 其中執行時資料區分為方法區(儲存如類資訊,方法資訊,引用,常量池等),堆(儲存類例項物件和陣列),java棧(以棧方式存放以幀為單位儲存執行緒的執行狀態幀),本地方法棧(跟本地方法相關的資料區),程式計數器(每一個執行緒都有它自己的程式計數器,表示下一條將被執行指令的“地址”)。

  • java應用啟動流程就是通過類載入子系統載入相關的類,然後把相關資料如類資訊,方法等存到方法區的棧中,例項化相關的類,同時把例項物件儲存在堆中,程式執行位置則是每個執行緒使用計數器來指定。方法區和堆是執行緒共享的,程式計數器及Java棧是執行緒私有的。

  • 執行時資料區是java應用執行時的監測區域,其中各個區域的記憶體情況,特別是堆的記憶體使用情況,是重點區域。堆還會分年輕代、年老代及 Metaspace,垃圾回收器會進行分代回收。通過它的回收情況監測,可以檢測到是否存在記憶體洩漏,而java棧則與執行緒有關,執行緒的執行狀態又與CPU相關,因此java棧的監測可以知道CPU佔用過大的問題,同時方法區和java棧的佔用記憶體大小也是一個監測的指標。

3 如何監測

經過上面的描述,我們大概已經知道一個java應用啟動後,我們為什麼需要監測java應用以及需要監測哪些東西。那落實到實際應用中,該如何進行監測呢?下面通過對java應用監測工具及方法進行一個概要介紹,後續將會以系列文章的形式,對各個監測工具及方法進行詳細介紹。

按監測工具的監測方式,主要分為以下四大類:

  • 程式內建-日誌及監控頁面
  • java自帶命令列監測工具
  • java自帶視覺化監測工具
  • 第三方診斷工具

3.1 程式內建監測

程式內建監測就比較簡單,在初學java時,最常用的就是使用System.out.println()把自己想要輸出的內容輸出,在開發階段也有人喜歡這樣,一方面可以輸出業務內容,監測功能的正常與否,另一方面可以輸出系統屬性System.getProperties()System.getProperty()。當然,現在更多的使用日誌框架進行輸出,並把日誌按級別輸出到檔案中,如log4jlogback。對於Spring Boot應用,還可以使用actuator來監測程式執行情況。tomcat容器自身也帶有監測頁面。此類監測主要特點是程式內建,並且通過日誌輸出來監測,開發人員相對比較熟悉了,一般來說在開發和測試階段比較常用,而生產環境下,日誌一般是error級別或者由於安全考慮,自帶的一些監測頁面有可能會關閉。因此,此類監測不再細說。

3.2 java自帶命令列監測工具

在jdk的安裝目錄下的的bin目錄,已經提供了多種命令列監測工具,以便於開發人員和運維人員監測java應用,同時方便開發及運維人員對問題進行診斷,因此,此類工具是java應用監測的重要手段。一般來說,常用的命令列工具包括jps,jinfo,jmap,jstack,jstat,其中

  • jps檢視java程式ID
  • jinfo檢視及調整虛擬機器器引數
  • jmap檢視堆(heap)使用情況及生成堆快照
  • jstack檢視執行緒執行狀態及生成執行緒快照
  • jstat顯示程式中的類裝載、記憶體、垃圾收集等執行資料。

通過這些工具,基本上可以瞭解java應用的記憶體變化狀態,執行緒執行狀態等資訊,進而為應用監測及問題診斷提供依據。後面的文章將會對這些工具進行詳細描述。

3.3 java自帶視覺化監測工具

除了命令列工具,在windows平臺下,jdk還提供了視覺化監測工具,以更直觀,更方便的方式對java應用執行狀況進行監測。這兩款工具分別是jconsolejvisualvm,在jdk下的bin目錄下可以找到。它們均可監測本地及遠端的java應用,包括堆使用情況,執行緒使用,cpu使用,類載入情況,gc情況,jvisualvm還可以生成相應的堆和執行緒快照,同時還可以使用相應的外掛,以便於進一步分析。後面的文章將會對這兩款工具的使用進行詳細描述。

3.4 第三方診斷工具

除了java自帶的工具,一些第三方的工具也是監測及分析診斷,效能調優的利器,包括MATBTraceArthas。其中

  • MATeclipse的記憶體分析外掛,通過MAT可以對dump出來的堆快照進行分析,並且輔助分析記憶體洩露原因,快速的計算出在記憶體中物件的佔用大小,垃圾收集器的回收工作情況,並可以通過報表直觀的檢視到可能造成這種結果的物件。
  • BTrace是是sun推出的一款Java 動態、安全追蹤(監控)工具,可以在不停機的情況下監控系統執行情況,並且做到最少的侵入,佔用最少的系統資源。特別適用在生產環境下對java應用進行監測,問題排查。
  • Arthas是阿里開源的線上Java診斷工具,同樣可以在不停機情況監控系統,包括記憶體情況,執行緒情況,GC情況,執行時資料,也可以監測方法引數、返回值,異常返回等資料,堪稱神器,在生產環境下使用非常方便。

後面的文章將會對這三款第三方工具的使用進行詳細描述。

4 總結

希望通過本系列的文章,讓大家可以對java的應用監測技術有所瞭解,熟悉各種監測工具,以便於在遇到線上問題(特別是效能問題,oom問題等),可以從容面對及處理。

參考資料

  • JVM規範:https://docs.oracle.com/javase/specs/jvms/se8/html/index.html
  • JDK工具參考檔案:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/
  • JAVA虛擬機器器體系結構:https://www.cnblogs.com/java-my-life/archive/2012/08/01/2615221.html
  • 書籍:《深入理解Java虛擬機器器-JVM高階特性與最佳實踐》-周志朋