JFR的學習
背景
某天晚上突然被拉上會
現場的現象是 服務重啟之後 大概在正常執行的
但是在第六個工作時間段小時開始出現卡頓.
然後從五一假期之後一直如此. 開會探討了很多
進行了很多猜測, 但是沒有證據
想到解決問題可能需要bpf,perf或者是jfr
但是因為以現場是容器執行的.
可能前面兩個有點難度. 所以想試試 jfr
問題的前期思考與整理
1. 最開始以為是系統長時間執行後效能下降.
但是經過檢視GC日誌. 發現YoungGC五分鐘一次, 一次100ms左右的停頓
時間沒有明顯變化, 所以認為不是這個原因.
2. 使用F12跟蹤網路
發現第一個等待回覆時長 8s + 後面的只需要不到 600ms完成
所以感覺有點像是建立連線或者是建立執行緒耗時.
3. 檢視top -Hp 和 jstack的資訊
發現C2程序只有 20min 的使用量 不是很高不是 codecache相關內容.
發現有14個左右的GC現場並且都是並行青年代和老年代
引數也沒有問題.
4. 發現不同點: Redis採用的哨兵,中介軟體用的是某國產中介軟體.
建議方式:
暫時替換為 tomcat 進行重啟. 驗證是否還卡頓
如果不卡頓了, 需要 國產中介軟體介入.
國產中介軟體的版本不太對, 好像是嵌入式版本, 建議升級商業伺服器版本
驗證問題的思路
雖然有懷疑是第一個回覆中間的耗時過長,
但是沒有證據.
跟最開始說的一樣, 本來想嘗試一下 bpf 或者是 perf
但是感覺不太行. 不一定好處理
然後想到前幾天看高手的jfr 的文章想嘗試一把
但是公司產品裡面預設的 jdk 1.8.222 不相容
所以這裡只能是做一個實驗, 而不是具體的問題解決了.
關於JFR
Java Flight Recorder (JFR)
是 Java 虛擬機器(JVM)的一個工具,
用於收集應用程式在執行時的各種資料,
包括方法呼叫、記憶體分配、執行緒活動等。它可以用於效能分析、故障排查和系統最佳化。
JFR 可以以低效能開銷的方式持續監視應用程式,當發生特定事件或達到特定條件時,
可以觸發記錄事件,生成詳細的記錄檔案,供後續分析使用。
JFR的簡單使用
JFR 一開始應該是 商業版才有的功能.
還未查到在那個版本下方到了OpenJDK8中
我這邊為了做實驗
將OpenJDK從 1.8.222 升級到了 1.8.402 畢昇JDK
操作如下:
jcmd 可以展示產品裡面在執行的java程序
jcmd $pid help 可以看到相關幫助
JFR.check
JFR.configure
JFR.dump
JFR.start
JFR.stop
檢視預設配置
JFR.configure
可以看到部分資訊
服務啟動之後
jcmd $pid JFR.start
然後可以透過
jcmd $pid JFR.dump
匯出為檔案.
透過
jcmd $pid JFR.check
確認任務名等資訊
下載JMC 進行分析
可以在oracle官方進行下載
需要注意 202405 下載的JMC 最新版本是 8.3.1
需要說明 JDK8 並不足以啟動這個服務
我這邊使用了最新的 JDK21 進行執行
開啟後使用 file 開啟檔案就可以分析