小記:本地服務耗時和上游調用顯示耗時相差過大問題排查及優化
問題
在最近一次壓測時發現了一個現象:監控顯示服務端p995耗時只有15ms左右,調用方的耗時卻高達2000ms,二者相差巨大。
定位過程
查看cpu
查看了壓測期間的cpu數據,發現cpu使用率只有20~30%,說明并不是cpu阻塞引起的調用方耗時高
查看jvm
查看了壓測期間的jvm數據,發現壓測期間并沒有出現full gc和年老代垃圾回收,young gc的次數和耗時也并沒有過多的上漲
問題縮小
排除了cpu和jvm后,猜測可能是處理網絡鏈接的rpc框架的線程池出現了積壓所致。
因為服務啟動時并沒有顯式的設置線程池數量,使用的默認配置。查詢了rpc框架的文檔,發現其默認線程池數量是30,隊列深度是30000。
根據這個數據推測是過少的線程池數量和過大的隊列深度,導致了上游調用出現了積壓,導致上游的耗時過長
改進
當前的容器是8核,一次請求平均耗時是15ms,那么一秒可以處理的線程數是 8*1000/15=533。考慮到cpu調度會占用一些時間,最終設置了450個線程數,900個隊列深度。
結果
調整了線程池配置后,在同樣的qps的情況下,上游調用方的耗時和本地服務端耗時相差就很小,當然cpu使用率也上升了。
小結
用餐廳來類比:廚師相當于cpu、餐桌數量相當于rpc框架線程池、 服務端耗時相當于客人到餐桌后吃飯所需時間、客人從來到離開時間是服務端調用時間。
如果廚師不忙,客人到餐桌后吃飯所需時間不長,但客人從來到離開時間確很長,就說明是餐桌過少,增加餐桌就可以了。
浙公網安備 33010602011771號