困擾好久的生產httpclient調用偶現socketTimeout異常


 

系統背景:

生產2台服務器,調用量高峰時期差不多15到20次每秒,每天差不多有50--80次的調用超時。之前也一直沒有在意。后來觀察日志發現,異常總是連續幾次的出現,不是一次一次的,這個現象引起了我的注意。

 

后來因為一次優化需求,后台我將請求調用方式改為了線程池的異步調用:

 

private static ExecutorService threadPool = Executors.newCachedThreadPool();

 

主線程要等線程池任務運行完返回結果集,才可以繼續運行,future來獲取多線程返回結果,每個線程中的任務包含一個http請求調用,上線后,接口速度因為異步處理,所以提高了50ms左右,還算比較樂觀,這樣線程正常運行了一段時間,超時還是有,這個問題沒有解決,因為沒有定位出原因。

生產故障

某天晚上,服務調用方晚上搞活動,調用量增加了原先的2到3倍,晚上內存出現告警80%以上,運維人員查看內存使用情況,swap區域已經使用了60%以上。這下肯定是內存滿了,晚上緊急情況,重啟了應用,暫時恢復了正常。正確的流程應該是先下個dump文件,再重啟的應用的。

 

第二天一早過來查問題,看系統運行情況,首先看jvm內存情況。

jstat -gcutil 25444 1000 20

 

發現比較異常的幾個參數,Old區有將近90%左右,s0 和s1兩者每次回收都有存留的值,正常應該一個是0的,最最要命的是FGCT幾十次,正常情況下,只要JVM內存參數設置合理,是不會有這么多的FGC的,於是問了運維人員,他們配置的是默認配置(非專業運維人員…尷尬)於是乎我們開始調整jvm運行參數

-xms 初始堆大小    調整為512M

-xmx 最大堆大小    調整為2048M

-XX:PermSize 設置持久代的最大值  調整為256M    -----這個調整對FGCT的參數影響很大,說明之前FGCT次數過多和持久代內存不足有很大關系,推算系統static的代碼區比較大

 

其他設置沒做太大改動

 

修改之后,FGCT直線下降,次數很小,S0和S1運行正常,O區 0% 增長十分緩慢,觀察一段時間后,各個區域運行正常。

 

好了,最最關鍵的來了,JVM調整參數之后,查看了一整天的日志,盡然沒有一次SocketTimtOut

 

原因分析: 當系統FGC的時候系統會stop the world,所以在這段時間內,會出現短暫的連續的超時。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM