在進行效能測試時,測試分析和調優是確保系統達到預期效能目標的重要步驟。本文介紹測試分析及效能調優的相關流程和方法,協助研發人員、測試人員或營運人員快速地進行效能測試、瓶頸定位及調優。 系統的效能是由很多因素決定的,本文很難面面俱到,但是可以作為分析系統效能的一個指導。
適用對象和範圍
適用於需要進行效能分析及調優的工作。 預期讀者為測試管理員、測試實施人員、技術支援人員、專案品質管理員、專案管理人員等系統技術品質相關人員。
效能分析
前提
效能分析的前提除了需要豐富的效能測試監控(如PTS自身的監控、基礎類監控-阿里雲監控、應用類監控-ARMS監控等),還需要具備相關的技術知識(包括但不限於:作業系統、中介軟體、資料庫、開發等)。
流程
效能分析是一個系統化的過程,旨在識別和解決系統中的效能瓶頸。以下是具體的效能分析步驟:
很多情況下壓測流量並沒有完全進入到後端(服務端),在網路接入層(雲化的架構,如SLB/WAF/高防IP,甚至是CDN/全站加速等)可能就會出現由於各種規格限制(如頻寬、最大串連數、建立串連數等),或者因為壓測的某些特徵符合CC和DDoS的行為而觸發了防護策略導致壓測結果達不到預期。更多資訊,請參見為什麼後端壓力不大但壓測時報錯或逾時?。
查看關鍵計量是否滿足要求。如果不滿足,需要確定是哪個地方有問題,一般情況下,伺服器端問題可能性比較大,也有可能是用戶端問題(這種情況非常少見)。
對於伺服器端問題,需要分析硬體相關指標,例如CPU,Memory,Disk I/O和Network I/O。如果某個硬體指標有問題,需要進行深入分析。
如果硬體指標都沒有問題,需要查看中介軟體相關指標,例如:線程池、串連池、GC等。
如果中介軟體相關指標沒問題,需要查看資料庫相關指標,例如:SQL慢查、命中率、鎖、參數設定。
如果以上指標都正常,應用程式的演算法、緩衝、緩衝、同步或非同步可能有問題,需要具體深入的分析。
瓶頸點
識別系統效能瓶頸是效能測試和調優的關鍵步驟。效能瓶頸是指系統中限制整體效能的部分,通常是資源不足或效率低下的地方。以下是一些常見的系統效能瓶頸:
硬體、規格上的瓶頸
一般指的是CPU、記憶體、磁碟I/O方面的問題。
中介軟體上的效能瓶頸
一般指的是應用伺服器、Web伺服器等應用軟體,還包括資料庫系統。 例如,中介軟體Weblogic平台上配置的JDBC串連池的參數設定不合理造成的瓶頸。
應用程式上的效能瓶頸
一般指的是開發人員開發出來的應用程式。 例如,JVM參數設定不合理、容器配置不合理、慢SQL(可使用阿里雲APM類產品如ARMS協助定位)、資料庫設計不合理、程式架構規劃不合理或程式本身設計有問題(串列處理、請求的處理線程不夠、無緩衝、無緩衝、生產者和消費者不協調等),造成系統在大量使用者訪問時效能低下而造成的瓶頸。
作業系統上的效能瓶頸
一般指的是Windows、UNIX、Linux等作業系統。 例如,在進行效能測試,出現實體記憶體不足時,虛擬記憶體設定也不合理,虛擬記憶體的交換效率就會大大降低,從而導致行為的回應時間大大增加,這時認為作業系統上出現效能瓶頸。
網路瓶頸
一般指的是防火牆、動態負載平衡器、交換器等裝置。當前更多的雲化服務架構使用的網路接入產品:包括但不限於SLB、WAF、高防IP、CDN、邊緣安全加速等。 例如,在動態負載平衡器上設定了動態分發負載的機制,當發現某個應用伺服器上的硬體資源已經到達極限時,動態負載平衡器將後續的交易請求發送到其他負載較輕的應用伺服器上。在測試時發現,動態負載平衡器沒有起到相應的作用,這時可以認為是網路瓶頸。
方法
瓶頸點分析方法用於識別系統中的效能瓶頸,並找出影響系統效能的關鍵限制因素。以下是一些常見的瓶頸點分析方法:
CPU
如果CPU資源使用率很高的話,需要查看CPU消耗User、Sys、Wait哪種狀態。
如果CPU User非常高,需要查看消耗在哪個進程,可使用
top(Linux)命令查看,接著用top -H -p <pid>查看哪個線程消耗資源高。如果是Java應用,就可以用jstack查看此線程正在執行的堆棧,瞭解資源消耗在哪個方法上,通常查看原始碼就能知道問題所在。如果是C++應用,可以用gprof效能工具進行分析。如果CPU Sys非常高,可以用
strace(Linux)查看系統調用的資源消耗及時間。如果CPU Wait非常高,可能是磁碟讀寫問題,可以通過減少日誌輸出、非同步或升級到更快的存放裝置。
Memory
作業系統為了最大化利用記憶體,一般都設定大量的Cache。因此,記憶體利用率高達99%並不是問題,分析記憶體問題主要查看某個進程佔用的記憶體是否非常大以及是否有大量的Swap(虛擬記憶體交換)。
磁碟I/O
磁碟I/O一個最顯著的指標是繁忙率。可以通過減少日誌輸出、非同步處理或升級到更快的存放裝置來降低繁忙率。
網路I/O
網路I/O主要考慮傳輸內容大小,不能超過硬體網路傳輸的最大值70%。可以通過壓縮減少內容大小、在本地設定緩衝以及分多次傳輸等操作提高網路I/O效能。
核心參數
核心參數一般都有預設值,這些核心參數預設值對於一般系統沒問題,但是對於壓力測試來說,可能啟動並執行參數將會超過核心參數,導致系統出現問題,可以用
sysctl來查看及修改。JVM
JVM主要分析GC、FULL GC是否頻繁,以及記憶體回收的時間。可以用
jstat命令來查看,對於每個堆大小以及GC頻繁,通過jmap將記憶體轉儲,再藉助工具HeapAnalyzer來分析哪地方佔用的記憶體較高以及是否有記憶體流失可能。簡單點可以使用APM工具,例如阿里雲ARMS。線程池
如果線程不夠用,可以通過調整參數增加線程。對於線程池中的線程設定比較大但仍然不夠用的情況,可能是某個線程被阻塞來不及釋放、可能在等鎖、方法耗時較長、資料庫等待時間很長等原因導致,需要進一步分析才能定位。
JDBC串連池
串連池不夠用的情況下,可以通過參數進行調整增加。但是對於資料庫本身處理很慢的情況下,調整沒有多大的效果,需要查看資料庫方面以及因代碼導致串連未釋放的原因。
SQL
SQL效率低下也是導致效能差的一個非常重要的原因。可以通過查看執行計畫看SQL慢在哪裡,一般情況,SQL效率低下原因主要有:
類別
子類
運算式或描述
原因
索引
未建索引
無
產生全表掃描
未利用索引
substring(card_no,1,4)=′5378′產生全表掃描
amount/30<1000產生全表掃描
convert(char(10),date,112)=′19991201′產生全表掃描
where salary<>3000產生全表掃描
name like '%Tom'產生全表掃描
first_name + last_name ='beill cliton'產生全表掃描
id_no in(′0′,′1′)產生全表掃描
select id from t where num=@num有參數也會產生全表掃描
使用效能低的索引
oder by非聚簇索引索引效能低
username='Tom' and age>20字串索引低於整型索引
表中列與空NULL值
索引效能低
盡量不要使用
IS NULL或IS NOT NULL索引效能低
資料量
所有資料量
select *很多列產生大量資料
select id,name表中有幾百萬行,產生大量資料
巢狀查詢
先不過濾資料,後過濾資料
產生大量無用的資料
關聯查詢
多表進行關聯查詢,先過濾掉小部分資料,在過濾大部分資料
大量關聯操作
巨量資料量插入
一次插入
產生大量日誌,消耗資源
鎖
鎖等待
update account set banlance=100 where id=10產生行級鎖,將會鎖住整個表
死結
A:update a;update b;B:update b;update a;將會產生死結
遊標
Cursor Open cursor,fetch;close cursor效能很低
暫存資料表
create tmp table建立暫存資料表產生大量日誌
DROP TABLE刪除暫存資料表
需要顯示刪除,避免系統資料表長時間鎖定
其他
EXISTS代替INselect num from a where num in(select num from b)IN會逐個判斷,EXISTS有一條就結束EXISTS代替select count(*)判斷記錄是否存在
count(*)將累加計算,EXISTS有就結束BETWEEN代替INID in(1,2,3)IN逐個判斷,BETWEEN是範圍判斷LEFT JOIN代替NOT INselect ID from a where ID not in(select b.Mainid from b)NOT IN逐個判斷,效率非常低UNION ALL代替UNIONselect ID from a unionselect id from b union重複資料刪除的行,可能會在磁碟進行排序而
UNION ALL只是簡單的將結果並在一起常用
SQL盡量用綁定變數方法insert into A(ID) values(1)直接寫SQL每次都要編譯,用綁定變數的方法只編譯一次,下次就可以用了
效能調優
效能調優是一個持續的過程,隨著應用的變化和使用者負載的增加,需要不斷進行監控和調整。週期性效能測試和分析可以協助及時發現問題,確保系統在各種負載條件下都能穩定運行。效能調優涵蓋多個方面,包括代碼最佳化、資料庫最佳化、伺服器配置、網路最佳化等。
調優步驟
確定問題
應用程式代碼:在通常情況下,很多程式的效能問題都是代碼問題。因此對於發現瓶頸的模組,應該首先檢查一下代碼。
資料庫配置:不合理的資料庫配置經常引起整個系統運行緩慢。一些大型資料庫都需要DBA進行正確的參數調整才能投產的。
作業系統配置:不合理的參數設定可能引起系統瓶頸。
硬體設定:磁碟I/O、記憶體大小等都是容易引起瓶頸的原因。
網路:網路負載過重可能導致網路衝突和網路延遲。
分析問題
當確定了問題之後,我們要明確這個問題影響的是回應時間、輸送量,還是其他問題?
是多數使用者還是少數使用者遇到了問題?如果是少數使用者,這幾個使用者與其他使用者的操作有什麼不同?
系統資源監控的結果是否正常?CPU的使用是否到達極限?I/O情況如何?
問題是否集中在某一類別模組中?
是用戶端還是伺服器出現問題? 系統硬體設定是否夠用?
實際負載是否超過了系統的負載能力? 是否未對系統進行最佳化?
通過這些分析及一些與系統相關的問題,可以對系統瓶頸有更深入的瞭解,進而分析出真正的原因。
確定調整目標和解決方案
高系統輸送量,縮短回應時間,更好地支援並發。
測試解決方案
對通過解決方案調優後的系統進行基準測試(基準測試是指通過設計科學的測試方法、測試載入器和測試系統,實現對一類測試對象的某項效能指標進行定量的和可對比的測試)。
分析調優結果
系統調優是否達到或者超出了預定目標。系統的整體效能是否得到了改善,還是以系統某部分效能來解決其他問題。調優是否可以結束了。 最後,如果達到了預期目標,調優工作可以先告一段落。
調優注意事項
在應用系統的設計開發過程中,應始終把效能放在考慮的範圍內,將效能測試常態化,日常化內網的效能測試,並定期對真實環境的業務進行效能測試。這些PTS都可以支援。
確定清晰明確的效能目標是關鍵,進而將目標轉化為PTS中的壓測情境並設定好需要的目標量級,然後視情況選擇並發、TPS模式,以及自動遞增/手工調速的組合進行流量控制。
必須保證調優後的程式運行正確。
系統的效能更大程度上取決於良好的設計,調優技巧只是一個輔助手段。
調優過程是迭代漸進的過程,每一次調優的結果都要反饋到後續的代碼開發中去。
效能調優不能以犧牲代碼的可讀性和可維護性為代價。
其他測試分析
成功率
成功率是根據服務端的傳回值以及斷言來判斷的。如果沒有配置斷言的情況下,後端服務返回錯誤響應碼、服務端異常或逾時都認為是失敗。
日誌
日誌是關於每個請求的內容。採樣率10%可以理解為100個請求採集10個請求的內容,採樣率100%的話表示每個請求都會記錄,但是會對施壓機效能造成影響,也會增加計費,日誌採樣率不影響服務端的。
建立串連
建立串連就是建立HTTP串連的過程。超過設定的建立連線逾時時間就認為這個請求逾時了,請求逾時時間為從DNS查詢算起,到接收完響應內容整個時間的閾值。