效能測試(四)常見調優
在效能測試過程中,最重要的一部分就是效能瓶頸定位與調優。而引發效能瓶頸的原因是多種多樣的,在之前的部落格:常見的效能測試缺陷有進行介紹。
這篇部落格,來聊聊效能測試過程中的一些注意事項,以及常見的一些效能缺陷表現及如何進行定位分析並且調優。。。
一、注意事項
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監控命令來排查,命令如下:
1 # 實時列印到螢幕 2 jstat -gc PID 300 10 3 jstat -gcutil PID 300 10 4 # GC資訊輸出到檔案 5 jstat -gc PID 1000 120 >>/path/gc.txt 6 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"
# 最大執行緒數,即服務端可以同時響應處理的最大請求數 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等,當然,分析定位後,你會發現,我們常見的效能瓶頸,
導致其的原因大多都是因為引數配置、服務策略、阻塞及各種鎖導致。。。
效能瓶頸分析參考準則:從上至下、從區域性到整體!