天天看點

記一次接口執行時間和響應時間相差大的排查過程

作者:IT技術控

一、背景

因為項目需要進行私有化部署,對系統關鍵業務的接口tps、qps都有要求,目标值為單台4C*8G機器qps需要達到250、tps達到200,且響應時間tp99低于300ms。是以利用jmeter對關鍵接口進行性能測試。

二、測試過程

機器配置:4C*8G(阿裡雲sae通用型6)

jvm參數配置為

ruby複制代碼-Xms5734M -Xmx5734M -Xmn4300M -Xss512k -XX:MetaspaceSize=200M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=85 -XX:+UseCMSInitiatingOccupancyOnly -XX:+PrintReferenceGC -XX:+ParallelRefProcEnabled -XX:+HeapDumpOnOutOfMemoryError
           

jmeter參數配置:

yaml複制代碼thread: 200
Ram-up period: 1
Loop count: 30
           

三、測試結果

通過配置的監控可看到實際qps為15,接口平均響應時間為1.8s,這跟目标要求相差甚遠,且與我的估算值也相差很大,因為這個接口我們做了大量的優化,基本不存在直接查詢資料庫的情況,對資料做了二級緩存(本地緩存+分布式緩存),并且浏覽器接口單次請求響應基本在30ms上下,這30ms包含了從接口傳回到頁面接收到資料的時間,也就是說伺服器接口時間還會比30ms小的多。而實際情況壓測情況來看比理論值相差了50倍

記一次接口執行時間和響應時間相差大的排查過程
記一次接口執行時間和響應時間相差大的排查過程

四、排查過程

1.檢視jvm監控,判斷是否jvm參數配置不合理,導緻大量的時間在gc。通過監控發現整個過程隻有14次youngGC,且沒有一次full gc。平均每次youngGC耗時400ms(由于年輕代配置的堆記憶體較大,也沒有細緻的對jvm參數調優,這個時間還算正常)。是以基本排除了gc導緻接口響應時間長的問題

記一次接口執行時間和響應時間相差大的排查過程

2.檢視cpu監控情況,發現cpu平均使用率為50%左右,最大值為71%,且系統負載也較低,是以也排除cpu的情況

記一次接口執行時間和響應時間相差大的排查過程
記一次接口執行時間和響應時間相差大的排查過程

3.根據日志鍊路追蹤檢視方法棧調用情況,發現整個接口耗時3s,實際接口處理邏輯隻有2ms,并且通過接口日志列印的時間發現也是2ms。

記一次接口執行時間和響應時間相差大的排查過程

通過調用棧看到整個耗時是在FrameworkServlet.doPost方法上,是以點開源碼進行分析,doPost實際執行processRequest方法,通過分析猜測可能finally執行的代碼塊存在耗時操作(日志列印,日志檔案寫入等操作?),而且finally裡面最後釋出一個RequestHandleEvent事件,表示着這個接口處理完成。是以我訂閱了一下這個事件,并event.getProcessingTimeMillis()輸出耗時時間,結果發現耗時也是毫秒級,說明finally代碼塊并不存在耗時邏輯。并且還排除自定義filter的攔截器耗時操作的可能性。

記一次接口執行時間和響應時間相差大的排查過程
記一次接口執行時間和響應時間相差大的排查過程

4.懷疑是否是帶寬限制導緻接口處理慢,由于網絡問題無法及時傳回,但是通過對此排查,發現網絡帶寬已經調整到最大,且帶寬并未打滿,是以不可能是網絡的問題,同時通過監控也排除了磁盤io問題

5.到此初步能想到的問題都排查了一遍,于是按照生産jvm的配置在本地啟動項目進行壓測,發現整個qps要比線上高很多,同時通過任務管理器發現此時電腦cpu已經達到100%

記一次接口執行時間和響應時間相差大的排查過程

這不禁讓我感到疑惑,因為在第二步的時候我就通過阿裡雲監控排查了機器cpu負載發現并不高,難道是監控的值不準确嗎?于是我直接進入線上容器同時進行壓測,通過指令檢視機器cpu負載情況,結果果真如猜想一樣,此時cpu負載持續超過200%,而監控上的負載卻隻有46%。

記一次接口執行時間和響應時間相差大的排查過程

到這基本上就已經确認是因為cpu負載高導緻的接口響應時間慢,前面說過,壓測的這幾個接口都屬于cpu密集型,而且接口耗時也比較短,是以推斷是因為tomcat線程數大(springboot預設線程數為200),線程之間頻繁切換導緻的。調整tomcat配置調整為如下,再重新開機服務進行壓測。

yaml複制代碼server:
  tomcat:
    max-threads: 8
    accept-count: 1000
    max-connections: 10000
    min-spare-threads: 8

           

測試結果為qps正常達到200,平均響應時間為72ms,最大響應時間為151ms;且通過後續壓測,qps能夠在1000控制平均響應時間為85ms左右

記一次接口執行時間和響應時間相差大的排查過程
記一次接口執行時間和響應時間相差大的排查過程

四、複盤

其實問題原因并不複雜,也還是常見的那些情況之一,在排查的第二步就已經接近真相,隻是被阿裡雲sae監控誤導了。

繼續閱讀