記憶體溢出排查
-
- 1. 頻繁FullGC預警
- 2. 排查原因
1. 頻繁FullGC預警
1.1 頻繁FullGC告警:
時間發生在2020-07-10(周五)晚上21:15分左右,本該收拾行囊下班,突然收到頻繁FullGC預警消息,吓的菊花一緊,過一會收到接口探活告警,說明服務已經不可用了;
1.2 下線目前問題節點:
服務是3台節點部署,既然其中一台出現問題,在上層網關上将目前節點下線,保證使用者的請求不會再打到目前節點;
1.3 年青代和老年代情況:
登入監控平台檢視jvm的情況:
黃色線:老年代
藍色線:年青化
在21:10左右時,就已經開始發生明顯的頻繁FullGC;
1.4 YGC次數和FGC次數:
登入監控平台檢視jvm的情況:
藍色:目前出問題節點的YGC總次數;
藍色:目前出問題節點的FGC總次數;
1.4 年青代具體情況:
黃色:S0;
紫色:S1;
藍色:Eden;
大概在21:10 - 21: 20這段時間一直在YGC
2. 排查原因
經過上面的分析,和上次遇到的頻繁FGC問題不一樣 上次的是突增,突然被記憶體被占滿,而本次的是存在緩慢的增長過程,猜測程式可能做了大批量導出;
2.1 生成dump檔案
檢視是否生成dump檔案,如果沒有生成,手動通過: jmap -dump:live,format=b,file=dump.hprof 程序号;生成dump檔案;
2.2 重新開機服務
既然記憶體快照儲存下來了,就可以放心的重新啟動服務;
2.3 檢視背景記錄檔
檢視背景記錄檔,發現使用者對一張擁有2200W記錄的表做了一次導出,但是導出的sql裡面有id值,按道理說隻會導出一條;也不會導緻程式記憶體溢出啊;
2.4 分析dump檔案
既然可疑的導出有明确指定id,不會造成大批量的資料被加載進服務,那隻能分析dump檔案
dump檔案大約28G,分析套路和 記一次排查線上頻繁FullGC 過程 一樣;
最後分析出來三個zip檔案,解析後檢視index.html;
大概占了24.3G,檢視詳細的調用棧;
還是出在導出的問題上;
2.5 檢視伺服器日志
經過精心排查伺服器日志發現,在使用者跳轉到查詢清單時,在沒有輸入任何查詢條件的情況下,點選過導出按鈕,造成大量記錄被加載進記憶體;
2.6 服務優化
1.導出的限制方面做控制;
2.大資料量導出考慮資料遷移到其它平台;
3.為什麼全量導出的操作沒有被記錄到記錄檔(待排查)
4.網關高耗時請求也考慮告警;