使用阿里雲aliyun-oss-java-sdk的 getObject方法返回的輸入流未主動釋放 導致http連接泄漏的線上問題排查

項目功能:基於netty的數據傳輸服務,接收客戶端數據,存在本地磁盤;定時任務,定時處理本地的文件,並上傳到阿里雲OSS
線上問題:運維監控發現過去半個小時都沒有記錄寫入到DB(因爲我們每上傳到OSS一次會DB記一條記錄)
問題排查過程

1、運維將實時的進程的dump文件拷貝出來

2、使用mat工具分析dump文件(mat介紹:https://www.cnblogs.com/trust-freedom/p/6744948.html

dump文件分析:

3、分析佔用內存最多、創建對象最多的對象.........分析了半天,並沒有定位問題,病急亂投醫:因爲我們默認懷疑是項目性能有問題,就從gc、cpu等去排查,其實根據dump文件的大小才1.5G,而線上的配置是4G,說明並不是項目性能有問題,由於經驗不足,希望能有實時線程的堆棧信息,但項目已經被運維重啓,無法獲取到線程的堆棧信息,問題排查陷入困境。後來懷疑是否是堆外內存有問題,因爲我們的開啓了DisableExplictGC這個參數,這個參數是禁用顯示調用System.gc()的,因爲堆外對象只能通過System.gc回收,禁用的話可能會導致堆外對象無法回收了,最終發現和這個沒有太大關係,因爲監控沒有發現堆外內存使用過度,日誌也沒有OOM的異常

4、後來有同事說,dump的文件裏,現在默認都會把線程的堆棧信息打印出來,用Mat工具可以直接看,汗顏啊,經驗不足,工具也不會用,如下的按鈕即可點出來了:

5、分析處理操作OSS相關的線程,發現8個線程都part了,問題原因找到,那麼爲什麼會part了

6、找到問題,就好解決了,有大神已經遇到過這個問題:https://github.com/aliyun/aliyun-oss-java-sdk/issues/10

從堆棧上是httpclient從連接池中獲取連接卡住:
可能有以下原因:

1. 連接泄漏,使用了getObject返回的輸入流,使用後一定要close;
2. 使用了getSimplifiedObjectMeta,2.2.3版本前有bug,沒有關閉連接;
3. 使用了2.1.2前的sdk版本, 2.1.2前的sdk使用http client 4.4,http client 4.4有bug,請升級sdk到2.1.2以上。
如果還沒有解決,請旺旺聯繫oss_support。

正好我們觸發了第一條:“使用了getObject返回的輸入流,使用後一定要close”,我們未關閉,導致http連接一直沒有釋放,前前後後排查問題耗時良久,主要還是經驗不足,本次記錄作爲一次積累吧。

發佈了142 篇原創文章 · 獲贊 345 · 訪問量 45萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章