聊聊企業級 Java 應用最重要的4個效能指標

segmentfault發表於2015-06-17

 1.商業事務

  商業事務是真實使用者體驗的直觀反映:它們抓取了使用者與應用互動時,使用者體驗到的實時效能資料。測量商業事務的效能,需要抓取一件商業事務整體的響應時間及其各個元件的響應時間。這些響應時間再與滿足業務需求的基準進行比較,從而決定應用是否正常。

  如果你只打算測量應用的一個方面,本文會推薦你測量商業事務的表現。儘管容量指標(container metrics)能幫助你決定何時調節叢集規模,但是商業事務才決定了應用本身的效能。你無需詢問應用伺服器執行緒池(thread pool)的使用情況,而是關心使用者能否迅速完成他們的商業事務,以及這些事務的表現是否正常。

  介紹一點背景知識:商業事務通過其入口進行辨別,即使用者與你的業務進行互動的入口。這類互動包括:一個網頁請求,一個網頁服務呼叫,或訊息佇列中的一條訊息。當然,你也可以基於一個 URL 引數為同樣的網頁請求定義多個入口,或基於一個服務呼叫的內容定義多個入口點。關鍵在於:商業交易必須與對你的業務流程相關聯,比如說中國移動的空中繳費業務對應到系統中是多個原子服務,我們就應該將這幾個原子服務通過相應的關聯聚合成一個空中繳費業務來進行監控。

  辨別某個商業交易後,它的效能就會在整個應用生態系統中進行測量。每個商業交易的效能會與其基準進行比較,判定其是否正常。譬如,如果某個商業事務的響應時間大於您設定的閾值,我們便判定其執行異常。

  總而言之,商業事務最能反映使用者體驗,因此它們也是最重要的抓取維度。

 2.外部服務

  外部服務的形式多種多樣:從屬的網頁服務、遺留系統或資料庫等。外部服務是與應用互動的系統。執行在外部服務系統中的程式碼常常無法控制,但是我們可以控制這些系統的配置,因此瞭解他們是否執行正常以及何時出錯也很重要。並且,我們必須有能力區分問題是出自自身應用,還是源於這些外部服務系統。

  從商業事務的角度來說,我們可以辨別並測量這些處於自身應用的外部服務。有時,我們需要配置監控方法從而辨別那些包裹了外部服務呼叫的方法。但是對於常見的協議,諸如 HTTP 和 JDBC,外部服務可以自動檢測。

  商業事務讓你對應用的效能有了全域性的掌控,幫助你對效能問題進行分類。但是外部服務總能以意想不到的方式極大地影響應用的執行,所以你必須監控它們。

 3.垃圾回收

  從 Java 釋出最早版本開始,一直都保留的核心特性就是垃圾回收,它真是讓人又愛又恨。垃圾回收使我們不再需要手動管理記憶體:當使用完一個物件後,我們只需刪除它的引用,然後垃圾回收就會自動釋放它。如果你使用過需要手動管理記憶體的語言,諸如C或C++,你會滿懷感激。垃圾回收為程式設計師們減少了分配、釋放記憶體空間的繁瑣步驟。

  此外,因為垃圾回收器會自動釋放沒有引用的記憶體空間,它減少了傳統的內容洩露情況,即記憶體被分配後,該記憶體的引用在記憶體釋放前就被刪除了。聽起來就像靈丹妙藥,不是麼?

  儘管垃圾回收達成了無需手動管理記憶體的目標,也防止了傳統的記憶體洩露,但是作為代價,垃圾回收過程有時相當笨拙。根據不同的 JVM,垃圾回收策略也會不同。深入探討這些策略超出了本文的主旨。但是,讀者應該明白,瞭解垃圾回收期的工作原理,以及最佳的配置方案至關重要。

  垃圾回收最大的敵人就是傳說中的主要 (major) 或 (full) 垃圾回收。除了 Azul JVM,所有的 JVM 都有這個問題。通常,垃圾回收大致分為兩類:

  • 次級
  • 主要

  為了釋放存活時間較短的物件,次級垃圾回收發生得相對頻繁。他們在執行時不會封鎖執行緒,產生的影響較小。

  然而,主要垃圾回收,有時也稱為“暫停世界(Stop The World, STW)”垃圾回收,因為他們在執行時會封鎖 JVM 中的所有執行緒。

  當垃圾回收執行時,它會執行一項可達性測試 (reachability test),如圖四所示。它會建立一個由物件組成的根集合 (root set),該集合包含每個執行執行緒中的直接可見物件。接著,它會探尋根集合中的物件涉及的其他物件,然後探尋這些物件涉及的物件,直到所有物件都被涉及。在這個過程中,它會記錄 (mark) 下現時活動物件的記憶體地址,然後把不被使用的所有地址都掃除 (sweep)。說得更恰當些,它會把沒有根集合物件引用的記憶體都釋放。最終,它會壓縮、整理這些記憶體,這樣新的物件才能獲得記憶體分配。

  根據不同的 JVM ,次級、主要回收的方式都會不同。圖五圖六展示了在Sun JVM內次級、主要回收的操作方式。

  在次級回收中,記憶體主要分配到 Eden 空間直到將其填滿。接著,拷貝收集器(copy collector)會將 Eden 中的活動物件拷貝到兩個倖存者空間(survivor spaces, to space和from space)。遺留在 Eden 中的物件就會被移除。如果倖存者空間被填滿,但還有多餘的活動物件,這些物件會被移到 tenured 空間。只有主要回收才能釋放tenured空間的記憶體。

  最終,tenured 空間會被填滿,主要回收將會執行。它不會將倖存者空間放不下的活動物件拷貝到 tenured 空間中。此時,JVM 會封鎖所有執行緒,執行可達性測試,清除年輕的資料(Eden和兩個倖存者空間),並壓縮 tenured 空間。我們將之稱為主要回收。

  你或許會想,堆越大,主要回收執行得越不頻繁。但是當它執行時,所需時間就會比小堆要長。因此,調整好堆的大小和垃圾回收策略對於應用的效能也很重要。

 4.應用佈局

  最後要探討的效能指標是應用佈局。因為雲的出現,現在的應用變得更加靈活:應用環境可以根據使用者需求調節大小。因此,對應用的佈局進行檢測從而決定例項的多少是否合適是非常重要的。如果你的例項太多,你的雲主機成本就會增加。但如果你沒有足夠的例項,商業事務就會受到影響。

  在評測過程中,下面兩個指標尤其重要:

  • 商業事務的吞吐量

  • 容器效能

  商業事務應該基準化,你應該知道在給定的時間裡為了滿足基準所需的例項數量。如果你的商業事務的吞吐量增長突然,你就要增加例項以滿足使用者。

  另一個需要監測的是容器效能。具體來說,你想確定是否有應用中的例項負載過大,如果有,你或許想在那個應用中新增例項。從應用的角度檢視例項狀態很重要,因為單個例項可能由於垃圾回收之類的因素負載過大,但如果應用中大多數例項都負載過大,則該應用可能已經無法支援它接受的訪問量。

  因為應用中的例項可以單個地調節規模,所以分析各個例項的效能進而調整應用佈局就至關重要。

  本文系 OneAPM 工程師陶炳哲整理。

相關文章