性能優化的流程詳解


一、流程圖

 

 

   在上述通用流程的四個步驟當中,步驟2和3我們會在接下來兩個部分重點進行介紹。首先我們來看一下,在准備階段和測試階段,我們需要做一些什么。

二、准備階段

  首先,需要對我們進行調優的對象進行詳盡的了解,所謂知己知彼,百戰不殆。

  a. 對性能問題進行粗略評估,過濾一些因為低級的業務邏輯導致的性能問題。譬如,線上應用日志級別不合理,可能會在大流量時導致 CPU 和磁盤的負載飆高,這種情況調整日志級別即可;

  b. 了解應用的的總體架構,比如應用的外部依賴和核心接口有哪些,使用了哪些組件和框架,哪些接口、模塊的使用率較高,上下游的數據鏈路是怎么樣的等;

  c. 了解應用對應的服務器信息,如服務器所在的集群信息、服務器的 CPU/內存信息、安裝的 Linux 版本信息、服務器是容器還是虛擬機、所在宿主機混部后是否對當前應用有干擾等;

  其次,我們需要獲取基准數據,然后結合基准數據和當前的一些業務指標,確定此次性能優化的最終目標。

  a. 使用基准測試工具獲取系統細粒度指標。可以使用若干 Linux 基准測試工具(eg. jmeter、ab、loadrunnerwrk、wrk等),得到文件系統、磁盤 I/O、網絡等的性能報告。除此之外,類似 GC、Web 服務器、網卡流量等信息,如有必要也是需要了解記錄的;

  b. 通過壓測工具或者壓測平台(如果有的話),對應用進行壓力測試,獲取當前應用的宏觀業務指標,譬如:響應時間、吞吐量、TPS、QPS、消費速率(對於有 MQ 的應用)等。壓力測試也可以省略,可以結合當前的實際業務和過往的監控數據,去統計當前的一些核心業務指標,如午高峰的服務 TPS。

二、測試階段

  進入到這一階段,說明我們已經初步確定了應用性能瓶頸的所在,而且已經進行初步的調優了。檢測我們調優是否有效的方式,就是在仿真的條件下,對應用進行壓力測試。注意:由於 Java 有 JIT(just-in-time compilation)過程,因此壓力測試時可能需要進行前期預熱。如果壓力測試的結果符合了預期的調優目標,或者與基准數據相比,有很大的改善,則我們可以繼續通過工具定位下一個瓶頸點,否則,則需要暫時排除這個瓶頸點,繼續尋找下一個變量。

  a. 性能瓶頸點通常呈現 2/8 分布,即80%的性能問題通常是由20%的性能瓶頸點導致的,2/8 原則也意味着並不是所有的性能問題都值得去優化;

  b. 性能優化是一個漸進、迭代的過程,需要逐步、動態地進行。記錄基准后,每次改變一個變量,引入多個變量會給我們的觀測、優化過程造成干擾;

  c. 不要過度追求應用的單機性能,如果單機表現良好,則應該從系統架構的角度去思考; 不要過度追求單一維度上的極致優化,實際環境是多系統、多服務的整體架構在工作,如可能過度追求 CPU 的性能而忽略了內存方面的瓶頸;

  d. 選擇合適的性能優化工具,可以使得性能優化取得事半功倍的效果;

  e. 整個應用的優化,應該與線上系統隔離,新的代碼上線應該有降級方案。

三、瓶頸點分析工具箱

  性能優化其實就是找出應用存在性能瓶頸點,然后設法通過一些調優手段去緩解。性能瓶頸點的定位是較困難的,快速、直接地定位到瓶頸點,需要具備下面兩個條件:

  • 恰到好處的工具;

  • 一定的性能優化經驗。

  工欲善其事,必先利其器,我們該如何選擇合適的工具呢?不同的優化場景下,又該選擇那些工具呢?

首選,我們來看一下大名鼎鼎的「性能工具(Linux Performance Tools-full)圖」,想必很多工程師都知道,它出自系統性能專家 Brendan Gregg。該圖從 Linux 內核的各個子系統出發,列出了我們在對各個子系統進行性能分析時,可使用的工具,涵蓋了監測、分析、調優等性能優化的方方面面。除了這張全景圖之外,Brendan Gregg 還單獨提供了基准測試工具(Linux Performance Benchmark Tools)圖、性能監測工具(Linux Performance Observability Tools)圖等,更詳細的內容請參考 Brendan Gregg 的網站說明。

  

 

上面這張圖非常經典,是我們做性能優化時非常好的參考資料,但事實上,我們在實際運用的時候,會發現可能它並不是最合適的,原因主要有下面兩點:

   1)對分析經驗要求較高。上面這張圖其實是從 Linux 系統資源的角度去觀測性能指標的,這要求我們對 Linux 各個子系統的功能、原理要有所了解。舉例:遇到性能問題了,我們不會拿每個子系統下的工具都去試一遍,大多數情況是:我們懷疑某個子系統有問題,然后根據這張圖上列舉的工具,去觀測或者驗證我們的猜想,這無疑拔高了對性能優化經驗的要求;

  2)適用性和完整性不是很好。我們在分析性能問題時,從系統底層自底向上地分析是較低效的,大多數時候,從應用層面去分析會更加有效。性能工具(Linux Performance Tools-full)圖只是從系統層一個角度給出了工具集,如果從應用層開始分析,我們可以使用哪些工具?哪些點是我們首先需要關注的?

  鑒於上面若干痛點,下面給出了一張更為實用的「性能優化工具圖譜」,該圖分別從系統層、應用層(含組件層)的角度出發,列舉了我們在分析性能問題時首先需要關注的各項指標(其中?標注的是最需要關注的),這些點是最有可能出現性能瓶頸的地方。需要注意的是,一些低頻的指標或工具,在圖中並沒有列出來,如 CPU 中斷、索引節點使用、I/O事件跟蹤等,這些低頻點的排查思路較復雜,一般遇到的機會也不多,在這里我們聚焦最常見的一些就可以了。

  對比上面的性能工具(Linux Performance Tools-full)圖,下圖的優勢在於:把具體的工具同性能指標結合了起來,同時從不同的層次去描述了性能瓶頸點的分布,實用性和可操作性更強一些。系統層的工具分為CPU、內存、磁盤(含文件系統)、網絡四個部分,工具集同性能工具(Linux Performance Tools-full)圖中的工具基本一致。組件層和應用層中的工具構成為:JDK 提供的一些工具 + Trace 工具 + dump 分析工具 + Profiling 工具等。

這里就不具體介紹這些工具的具體用法了,我們可以使用 man 命令得到工具詳盡的使用說明,除此之外,還有另外一個查詢命令手冊的方法:info。info 可以理解為 man 的詳細版本,如果 man 的輸出不太好理解,可以去參考 info 文檔,命令太多,記不住也沒必要記住:

 

 上面這張圖該如何使用?下期再詳細分享

 

四、常見調優思路有哪些?

  在通過工具得到異常指標,初步定位瓶頸點后,如果進一步進行確認和調優?我們在這里提供一些可實踐、可借鑒、可參考的性能調優「套路」,即:如何在眾多異常性能指標中,找出最核心的那一個,進而定位性能瓶頸點,最后進行性能調優。以下會按照代碼、CPU、內存、網絡、磁盤等方向進行組織,針對對某一各優化點,會有系統的「套路」總結,便於思路的遷移實踐。

  1、代碼相關

  遇到性能問題,首先應該做的是檢查否與業務代碼相關——不是通過閱讀代碼解決問題,而是通過日志或代碼,排除掉一些與業務代碼相關的低級錯誤。性能優化的最佳位置,是應用內部。

  2、 CPU 相關

  我們更應該關注 CPU 負載,CPU 利用率高一般不是問題,CPU 負載 是判斷系統計算資源是否健康的關鍵依據。

  3、內存相關

  內存分為系統內存和進程內存(含 Java 應用進程),一般我們遇到的內存問題,絕大多數都會落在進程內存上,系統資源造成的瓶頸占比較小。對於 Java 進程,它自帶的內存管理自動化地解決了兩個問題:如何給對象分配內存以及如何回收分配給對象的內存,其核心是垃圾回收機制。

  4、磁盤I/O和網絡I/O

  以上是性能優化的流程詳解,下篇再詳細分享《性能常用優化工具實戰》

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM