性能測試常見瓶頸分析及調優方法

  • 2019 年 12 月 2 日
  • 筆記

在性能測試過程中,最重要的一部分就是性能瓶頸定位與調優。而引發性能瓶頸的原因是多種多樣的,在之前的部落格:常見的性能測試缺陷有進行介紹。這篇文章,來聊聊性能測試過程中的一些注意事項,以及常見的一些性能缺陷表現及如何進行定位分析並且調優。。。

一、注意事項

1、斷言

在壓測時,為了判斷發送的請求是否成功,一般會通過對請求添加斷言來實現。使用斷言時,建議遵循如下規範:

①、斷言內容盡量以status/code、msg/message來判斷(當然前提是介面設計遵循Restful規範)

Jmeter示例:

阿里雲PTS:

如果使用的是PTS壓測,則斷言設置中,以code/status、msg/message等於對應的值為準;

②、儘可能不要將所有的Response Body內容作為斷言判斷的內容,這樣很可能會導致大量的「斷言」失敗;

PS:然後很遺憾的是,見過很多做壓測的童鞋,斷言內容以整個響應參數內容做斷言,導致大量的報錯。

2、成功率

一般在性能測試中,我們都追求99.99%的成功率,但在實際的測試過程中,為了儘可能覆蓋程式碼邏輯,在準備階段會儘可能的準備較多的熱點數據去做到覆蓋。這樣的話,我們所關注的成功率指標,就要分為如下兩種:

①、事務成功率

事務成功率在某些時候也可以視為請求成功率,在斷言判斷時以code/status等內容來作為請求是否成功的衡量依據;

②、業務成功率

實際的業務場景中,所謂的成功率,並不能僅根據返回的code/status來判斷。比如:一個查詢請求,無論是返回正確的查詢結果還是由於對應數據返回空,這個請求都是成功的。

對應的響應參數可能是: {"status":"200","message":"success"} ;也可能是: {"status":"200","message":"暫無對應結果"} 。

PS:在性能測試過程中,考慮到業務成功率和請求成功率的不同指標,結合斷言內容,需要靈活設置斷言的方式(當然,我依然建議遵循如上的2點斷言規範)!

二、常見性能瓶頸解析及調優方案

在性能測試中,導致性能出現瓶頸的原因很多,但通過直觀的監控圖表現出來的樣子,根據出現的頻次,大概有如下幾種:

性能瓶頸出現頻次

具體表現

TPS波動較大

高並發下大量報錯

集群類系統,各服務節點負載不均衡

並發數不斷增加,TPS上不去,CPU耗用不高

壓測過程中TPS不斷下降,CPU使用率不斷降低

下面對常見的幾種性能瓶頸原因進行解析,並說說常見的一些調優方案:

1、TPS波動較大

原因解析:出現TPS波動較大問題的原因一般有網路波動其他服務資源競爭以及垃圾回收問題這三種。

性能測試環境一般都是在內網或者壓測機和服務在同一網段,可通過監控網路的出入流量來排查;

其他服務資源競爭也可能造成這一問題,可以通過Top命令或服務梳理方式來排查在壓測時是否有其他服務運行導致資源競爭;

垃圾回收問題相對來說是最常見的導致TPS波動的一種原因,可以通過GC監控命令來排查,命令如下:

# 實時列印到螢幕  jstat -gc PID 300 10  jstat -gcutil PID 300 10  # GC資訊輸出到文件  jstat -gc PID 1000 120 >>/path/gc.txt  jstat -gcutil PID 1000 120 >>/path/gc.txt

調優方案

網路波動問題,可以讓運維同事協助解決(比如切換網段或選擇內網壓測),或者等到網路較為穩定時候進行壓測驗證;

資源競爭問題:通過命令監控和服務梳理,找出壓測時正在運行的其他服務,通過溝通協調停止該服務(或者換個沒資源競爭的服務節點重新壓測也可以);

垃圾回收問題:通過GC文件分析,如果發現有頻繁的FGC,可以通過修改JVM的堆記憶體參數Xmx,然後再次壓測驗證(Xmx最大值不要超過服務節點記憶體的50%!)

2、高並發下大量報錯

原因解析:出現該類問題,常見的原因有短連接導致的埠被完全佔用以及執行緒池最大執行緒數配置較小超時時間較短導致。

調優方案

短連接問題:修改服務節點的tcp_tw_reuse參數為1,釋放TIME_WAIT scoket用於新的連接;

執行緒池問題:修改服務節點中容器的server.xml文件中的配置參數,主要修改如下幾個參數:

# 最大執行緒數,即服務端可以同時響應處理的最大請求數  maxThreads="200"  # Tomcat的最大連接執行緒數,即超過設定的閾值,Tomcat會關閉不再需要的socket執行緒  maxSpareThreads="200"  # 所有可用執行緒耗盡時,可放在請求等待隊列中的請求數,超過該閾值的請求將不予處理,返回Connection refused錯誤  acceptCount="200"  # 等待超時的閾值,單位為毫秒,設置為0時表示永不超時  connectionTimeout="20000"         

3、集群類系統,各服務節點負載不均衡

原因解析:出現這類問題的原因一般是SLB服務設置了會話保持,會導致請求只分發到其中一個節點。

調優方案:如果確認是如上原因,可通過修改SLB服務(F5/HA/Nginx)的會話保持參數為None,然後再次壓測驗證;

4、並發數不斷增加,TPS上不去,CPU使用率較低

原因解析:出現該類問題,常見的原因有:SQL沒有創建索引/SQL語句篩選條件不明確、程式碼中設有同步鎖,高並發時出現鎖等待;

調優方案

SQL問題:沒有索引就創建索引,SQL語句篩選條件不明確就優化SQL和業務邏輯;

同步鎖問題:是否去掉同步鎖,有時候不僅僅是技術問題,還涉及到業務邏輯的各種判斷,是否去掉同步鎖,建議和開發產品同事溝通確認;

5、壓測過程中TPS不斷下降,CPU使用率不斷降低

原因解析:一般來說,出現這種問題的原因是因為執行緒block導致,當然不排除其他可能;

調優方案:如果是執行緒阻塞問題,修改執行緒策略,然後重新驗證即可;

6、其他

除了上述的五種常見性能瓶頸,還有其他,比如:connection reset、服務重啟、timeout等,當然,分析定位後,你會發現,我們常見的性能瓶頸,

導致其的原因大多都是因為參數配置、服務策略、阻塞及各種鎖導致。。。

性能瓶頸分析參考準則:從上至下、從局部到整體!

以上分析及調優方案僅供參考,具體定位還需要根據日誌監控等手段來分析調優。。。