“時間”都去哪兒了?效能調優分析方法與案例詳解

京東科技開發者發表於2021-03-17

原創 侯龍

“時間”都去哪兒了?效能調優分析方法與案例詳解


一個好的軟體,功能和效能都至關重要,這當然離不開產品同學的開光腦瓜、研發同學的靈巧小手,也離不開測試同學的金晶火眼。說到測試,可能大家就會想到頁面點點點呀,介面驗證呀,業務聯調呀等等,其實還有一個很重要的環節,那就是效能測試。

那麼,什麼是效能測試?如何衡量系統效能?系統響應時間是怎麼計算的?如何進行效能調優?帶著這些問題,我們們今天就來簡單地聊一聊效能調優那些事兒。


1.效能測試是什麼

效能測試就是透過特定的方式,對被測系統按照一定的測試策略施加壓力,獲取該系統的響應時間、吞吐量、資源利用率等效能指標,來檢驗系統上線後能否滿足使用者需求的過程,主要包括測試需求/目的、測試環境/工具、測試方案、測試執行、測試結果與分析。

2.衡量系統的四大指標

衡量一個系統的效能,主要有以下四大指標:

響應時間

指應用執行一個操作所需的時間,包括從發出請求開始到最後收到響應所需要的時間。響應時間是系統最重要的效能指標,直觀的反映了系統的快慢。

吞吐量

指單位時間內系統處理的請求數,體現系統的整體處理能力。TPS(Transaction per second)是吞吐量的一個常用量化指標,此外還有HPS(Hits per second)、QPS(Query per second)等。

資源利用率

指應用伺服器、資料庫伺服器及被測系統包含的中介軟體伺服器的CPU、記憶體、磁碟、網路等系統資源的使用情況。

併發數

指的是同時提交請求的使用者數目。這四個指標之間的關係如圖1。


“時間”都去哪兒了?效能調優分析方法與案例詳解
圖1



吞吐量= 併發數/平均響應時間吞吐量= 併發數/平均響應時間。

從圖1我們可以看到:

  • 當系統壓力較小時,響應時間幾乎無變化,吞吐量和系統資源隨併發數的增加呈線性增長趨勢;

  • 當系統壓力較大時,隨著併發數增加,響應時間也逐漸增加,系統資源達到極限,吞吐量不再增長;

  • 繼續增加併發數,響應時間快速增長,系統資源仍然在極限狀態,吞吐量迅速下降。

一般情況下,我們希望系統能夠支援更大的併發和更大的吞吐量。但是,從上面的分析我們可以看到,併發數的增長不會一直帶來吞吐量的增長,因為系統資源使用率達到極限後,響應時間將會是決定吞吐量的更大因素,那麼,時間都去哪兒了呢?

3.時間都去哪兒了


“時間”都去哪兒了?效能調優分析方法與案例詳解
圖2


一個請求從發出到接收響應,如圖2所示。大致流程如下:

  1. 客戶端傳送請求報文。客戶端傳送請求報文,經過網路傳輸後到達服務端;

  2. 服務端處理。服務端接收到請求報文後,進行業務邏輯處理和必要的資料讀寫操作;

  3. 服務端返回響應報文。服務端處理完後,將響應報文傳送到客戶端。

我們通常說的響應時間是第1步、第2步、第3步消耗的總時間。第1步主要是客戶端請求耗時和網路耗時;第2步主要是業務邏輯、資料讀寫和網路耗時;第3步主要是客戶端渲染和網路耗時。

第1、2、3步每一步都有可能存在效能問題,導致響應時間變長。第1步中如客戶端主機配置低,反應慢等,第二步中如業務執行緒阻塞、資料庫查詢慢;第3步中如網路傳輸延遲。根據各種問題的型別,我們又可以把問題歸為硬體問題、網路問題、程式碼問題、中介軟體問題等。不同問題也有不同的調優方法,下面我們簡單聊一聊效能調優。

4.抓住時間的小偷-效能調優

常用的調優方法有:

  • 空間換時間。如資料快取,提前從磁碟上讀取資料快取到記憶體中,CPU請求資料直接從記憶體中獲取,從而達到更高的效率;


  • 時間換空間,如上傳大附件,將資料分批次處理,用更少的空間完成任務處理;


  • 分而治之,把任務切分,分開執行,也方便並行執行來提高效率;


  • 非同步處理,如網際網路應用最常見的MQ訊息佇列,將業務鏈路上比較耗時的業務拆分出來,透過非同步處理減少阻塞影響;


  • 並行,多個程式或者執行緒同時處理業務,縮短業務處理時間;


  • 離使用者更近一點,如CDN技術,把使用者請求的靜態資源放在離使用者更近的地方;


  • 一切可擴充套件,業務模組化、服務化(同時無狀態化)、良好的水平擴充套件能力。

下面我們舉幾個案例進行說明。


案例1

問題描述:壓測某介面時,隨著壓測執行,響應時間越來越長。

問題分析:

  1. 列印執行緒堆疊,對比執行緒堆疊資訊,發現執行緒堆疊中FailoverEvent的執行緒數越來越多,最終記憶體溢位;

  2. 檢視程式碼發現,程式中未判斷FailoverEvent執行緒佇列是否已經存在,導致FailoverEvent執行緒佇列重複建立。


“時間”都去哪兒了?效能調優分析方法與案例詳解



解決方案:建立FailoverEvent執行緒佇列前,判斷其是否存在,如果不存在則建立,如果存在,則使用現有物件。

最佳化結果:記憶體溢位問題解決,響應時間正常。

調優建議

  1. 儘早釋放無用物件的引用;

  2. 程式進行字串處理時,儘量避免使用String,而應使用StringBuffer;

  3. 儘量少用靜態變數;

  4. 避免集中建立物件尤其是大物件;

  5. 儘量運用物件池技術以提高系統效能;

  6. 不要在經常呼叫的方法中建立物件,尤其是忌諱在迴圈中建立物件。


案例2

問題描述:某批次處理介面,無積壓的情況下,10000訂單,4500sku種類處理時間耗時433秒。

問題分析:介面中採用單執行緒方式呼叫下游服務,查詢次數=sku種類數/11,4500sku種類約410次,且每次呼叫耗時約519ms。


“時間”都去哪兒了?效能調優分析方法與案例詳解


解決方案:呼叫下游服務改用多執行緒方式。


“時間”都去哪兒了?效能調優分析方法與案例詳解



最佳化結果:TP99由212秒下降到33秒,TPS由87筆/秒提升到127筆/秒。

調優建議:本案例採用多執行緒降低了響應時間,但並不是說多執行緒一定比單執行緒快,因為幹活的是CPU,不是執行緒。我們可以透過確認系統有無磁碟/網路IO來進行選擇,有,多執行緒;無,單執行緒。並且採用多執行緒時,一定要使用執行緒池。

案例3

問題描述:資料查詢介面,TP99=727ms,加大併發,吞吐量無法提升,應用伺服器CPU使用率始終不到40%。

問題分析:透過呼叫鏈分析我們發現,一次請求,呼叫了11次selectList方法,導致介面總耗時飆升。


“時間”都去哪兒了?效能調優分析方法與案例詳解


解決方案:去掉冗餘呼叫,一次請求呼叫一次selectList方法。


“時間”都去哪兒了?效能調優分析方法與案例詳解


最佳化結果:TP99由727ms下降到19ms,提升38倍,TPS由17.5筆/秒提升至163.4筆/秒,提升9倍。

調優建議

  1. 設計先於程式碼;

  2. 基本原則:把資料庫操作放在迴圈之外;

  3. 如果是查詢,使用IN查詢替換for迴圈(空間換時間);

  4. 如果是新增,使用批次插入。


案例4

問題描述:某介面提交資料庫操作,更新資料時產生死鎖。

問題分析:產生死鎖的事務如表1:


“時間”都去哪兒了?效能調優分析方法與案例詳解


解決方案:將事務1拆分,先查詢,然後根據查詢的結果批次刪除。

最佳化結果:死鎖問題解決。

調優建議

  1. 避免大事務;

  2. 按同一順序訪問資料對;

  3. 避免編寫包含使用者互動的事務;

  4. 酌情使用低隔離級別,如RC;

  5. 為表新增合理的索引,如果不走索引將會為表的每一行記錄加鎖,死鎖的機率就會大大增大;

  6. 避免在同一時間點執行多個對同一表進行讀寫的指令碼,特別注意加鎖且運算元據量比較大的語句;

  7. 設定鎖等待超時引數,innodb_lock_wait_timeout。

5.總結

響應時間通常只是問題的表現,根本原因在於各種資源的利用是否合理,這裡的資源是指廣義的資源,包括硬體/軟體資源、系統/執行緒/資料等不同級別的資源。調優本身,就是對各種資源進行更合理的配置。調優的目的通常也是為了滿足業務需求,因此我們不必追求過早和過度最佳化,並且我們應該認識到,效能調優不可能一勞永逸,隨著業務的迭代,總會有新的問題出現,因此我們應該具備打持久戰的共識和能力。



歡迎點選【 京東科技 】,瞭解開發者社群

更多精彩技術實踐與獨家乾貨解析

歡迎關注【京東科技開發者】公眾號






來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69912185/viewspace-2763236/,如需轉載,請註明出處,否則將追究法律責任。

相關文章