java內存溢出的排查記錄

問題

     背景:服務異常,交易無法發到服務器,經排查發現大量SYN_RECV,重啓服務後交易正常。有大量CLOSE_WAIT、SYN_RECV連接,交易日誌無增量輸出,每次重啓後不久服務又出現無法訪問現象,反覆重啓3次後,截止發郵件時生產上仍有CLOSE_WAIT,CLOSE_WAIT、SYN_RECV許多連接爲F5地址,懷疑可能由F5引起大量非正常連接,進而導致交易無法正常使用。console.log中出現java.lang.OutOfMemoryError

問題排查及分析

  1. 收集相關信息。確認異常,明確現象: 
    1. 大量close_wait:根據TCP三次握手建立通訊可以知道,這個一般是在服務端出現的。排除惡意攻擊的情況,只會在客戶端斷開鏈接之後服務端未及時關閉鏈接時出現;具體流程見相關文章
    2. 內存溢出:java.lang.OutOfMemoryError: Java heap space ;該異常爲內存不足,一般是程序問題導致的。
    3. 在JVM參數中新增下列參數,在JVM虛擬機發生內存溢出異常時,自動產生DUMP文件
    4. #當應用拋出 OutOfMemoryError 時自動生成dump文件

      -XX:+HeapDumpOnOutOfMemoryError

      #dump文件輸出路徑

      -XX:HeapDumpPath=/home/sunefrs/sunefrs.dump

    5. 從dump文件上看,Log4j佔用了大量內存.其回根收節點見下圖
  2. 分析當前可能引起異常現象的可能原因:
    1. 生產日誌量很大,大部分爲圖片比對交易,交易報文一般在幾百K到1、2M不等,暫未發現超大報文的情況。
    2. 有大量F5調用異常。
    3. dump文件顯示:有大量內存被log4j佔用了。很可能是因爲日誌打印問題。
  3. 確認可能原因是否成立:
    1. F5正常。不太可能是F5造成的
    2. 日誌量很大,從dump文件分析有極大可能是由於log4j打印日誌造成的
  4. 復現生產問題步驟:
    1. 使用jmeter進行壓測。使用大報文模擬交易。
    2. 打開java visualVm 監控內存使用情況
    3. 打開console.log監控控制檯日誌
    4. 使用netstat命令監控close_wait情況【此處不放截圖,僅說結論】:
      1. 60併發壓測:屏蔽日誌打印,垃圾回收正常,交易未出現問題
      2. 60併發壓測:不屏蔽日誌打印,垃圾無法及時回收,交易OOM,並出現大量close_wait【之前測試沒出現是因爲設置了Keep-Alive參數
  5. 問題原因分析:
    1. 從業務日誌上看,交易報文比較大,在日誌打印的時候會把字段打印出來如下:日誌量將會是8倍,如果是2M圖片,會寫16M以上日誌【這裏取值有點問題,正常生成是會寫8倍日誌的】【補充說明:實際上還有16進制的日誌打印也會有2次,比原圖片還大的多圖片未寫出來】
    2. 再看log4j配置文件:日誌是異步打印的。當交易量較大的時候。日誌打印量會超級大,假設每次報文圖片大小爲2M,有每分鐘20個請求,每分鐘就會有320M以上的日誌量。且目前生產log4j配置爲兩處輸出,因此日誌量*2也就是640M以上,加上其他交易的日誌,日誌量會非常大。
      【測試環境寫磁盤速度大約爲87.2MB/sec,考慮到還有日誌壓縮和其他系統的讀寫,程序寫日誌不會把寫磁盤速度用滿。因此會有大量日誌停留在內存中。因此會造成內存溢出。內存溢出後程序直接卡死,不能正常處理交易且無法恢復】
  6. 驗證分析:
    1. 單線程且間隔較大時間調用交易:交易正常內存正常回收
    2. 高併發調用交易:程序快速內存溢出
    3. 關閉日誌:高併發內存快速釋放,交易正常 

總結

         內存溢出原因爲:日誌打印量過大,佔用了過多磁盤資源,寫日誌的速度跟不上新增待寫日誌速度導致。

         查內存溢出最重要的就是要找到是什麼類佔用了內存,爲什麼不能正常釋放。明確了這兩點。內存溢出問題就不難解決。

解決方案

  1. 推薦方案:使用log4j過濾器,屏蔽圖片字段相關打印。移除多餘的日誌打
  2. 可選方案:分多個jvm處理類似大報文的交易,把這個jvm的log4j文件直接屏蔽日誌。
  3. 可選方案:修改底層代碼,調整日誌打印方式。

參考文章

  1. TCP狀態變更流程:https://www.cnblogs.com/qingergege/p/6603488.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章