CosClient連接池泄露

簡單描述一下處理的過程。

因?yàn)槭切聶C(jī)器,又著急發(fā)布,很多監(jiān)控組件并沒有集成進(jìn)去,很多東西也是手工操作,相當(dāng)痛苦(很不規(guī)范),大致的順序如下:

0、服務(wù)發(fā)布幾天了,流量特別小。
1、早上要發(fā)布新功能,由于該沒有集成到CI/CD上,所以只能純手工啟動。把服務(wù)啟動,因?yàn)榭吹皆瓉矸?wù)啟動時(shí)沒有指定內(nèi)存大小,所以修改了啟動命令。

原命令:nohup java -jar springtboot.jar &
加上參數(shù):-server -Xms2g -Xmx2g

2、服務(wù)有三臺,逐個(gè)啟動。
3、啟動后看日志,暫時(shí)沒有問題。
4、上游說有一批數(shù)據(jù)需要處理,意味著流量會進(jìn)來,進(jìn)來的方式主要是kafka
5、服務(wù)正常的消費(fèi),處理,看kafka的監(jiān)控大盤,問題不大
6、過了一會,消息提醒,xxxtopic有消息堆積,請盡快處理...
7、上kafka監(jiān)控大盤一看,確實(shí)有不少消息堆積,消費(fèi)速率降為0
8、打開一臺機(jī)器查看服務(wù)。
9、top 看指標(biāo),CPU偏高,說明服務(wù)還在處理,主要是服務(wù)在處理數(shù)據(jù)時(shí)是偏吃CPU性能操作??碦ES,此時(shí)已經(jīng)去到2.8G了。(沒有把2.8G跟啟動服務(wù)時(shí)新加上的配置聯(lián)系上)
10、free看指標(biāo),內(nèi)存夠夠的
11、tail -f 查看日志,日志不滾動了。
12、下載arthars 查看,通過thread命令看到很多線程,處于WAITING狀態(tài)(Threads Total超過4k個(gè)線程),但是線程名稱是默認(rèn)的,從名稱上看不出來什么。此時(shí)通過dashboard看到gc count很大,也就是一直在做gc,存在對象沒有及時(shí)釋放。所以CPU一直偏高可能是因?yàn)橐恢痹谧鰃c。
13、此時(shí)退出arthar后。ps -ef | grep java找到pid,dump出內(nèi)存信息,jmap -dump:live,format=b,file=heap.hprof pid
14、一邊下載heap.hprof,一邊把參數(shù)調(diào)上去-Xms4g -Xmx4g并重新啟動服務(wù),先讓能繼續(xù)提供服務(wù)。(毫無疑問,內(nèi)存還在持續(xù)緩慢的上升)
15、通過MAT打開heap.hprof,看到有對象存在4k個(gè)對象,并且是騰訊云Cos服務(wù)的連接監(jiān)控線程對象。此時(shí)大概猜到,估計(jì)是CosClient的相關(guān)資源沒有釋放,查閱業(yè)務(wù)代碼發(fā)現(xiàn)沒有對CosClient做資源的釋放。(shutdown方法)
16、翻看CosClient源代碼,找到IdleConnectionMonitorThread對象,是客戶端的連接池監(jiān)控線程,這個(gè)線程只是每隔2s去清理一下expire conntion 、idle connection。這個(gè)線程隨著CosClient創(chuàng)建出來一起被new出來,并且該線程被設(shè)置為守護(hù)線程。因?yàn)榫€程一直在運(yùn)行,所以引用會一直存在,故而無法被回收。
17、把CosClient改成單例后重新發(fā)布,經(jīng)觀察問題不存在,算是解決了。(官網(wǎng)也提到CosClient是線程安全,原文是:COSClient 是線程安全的類,允許多線程訪問同一實(shí)例。因?yàn)閷?shí)例內(nèi)部維持了一個(gè)連接池,創(chuàng)建多個(gè)實(shí)例可能導(dǎo)致程序資源耗盡,請確保程序生命周期內(nèi)實(shí)例只有一個(gè),并在不再需要使用時(shí),調(diào)用 shutdown 方法將其關(guān)閉。如果需要新建實(shí)例,請先將之前的實(shí)例關(guān)閉。https://cloud.tencent.com/document/product/436/10199

image.png

1、操作很不規(guī)范,日常絕大多數(shù)時(shí)候都是運(yùn)維同學(xué)幫忙操作,很多時(shí)候只看到heap.hprof文件,并根據(jù)文件去找到泄露的對象,再去定位代碼,在機(jī)器上實(shí)操較少。
2、arthas很少用,查了一些命令行非常豐富,很有必要深入學(xué)習(xí)一下,在生產(chǎn)排查問題絕對是利器。
3、因?yàn)楸痉?wù)endpoint只有消息隊(duì)列,有很好的重試機(jī)制以及程序的冪等處理,故而在服務(wù)節(jié)點(diǎn)上的重啟成本較低,如果是基于微服務(wù)間連接的方式,比如dubbo或者eureka,一般沒有很好的重試機(jī)制就需要一些優(yōu)雅的上下線機(jī)制來協(xié)助。比如在heap dump前盡量從服務(wù)集群中摘除,切斷流量入口,然后再操作。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容