問題描述
flink+kafka,某些時候會有消息規程,量不大,但緩慢上升。
初步排查:
kafka集群正常,消息接入,節點,內存,CPU均正常。
寬帶正常。
flink反壓正常。
--本文問題由flink+kafka引出,但與kafka和flink技術本身無關。
--本文主要記錄內存CPU高的解決思路做一次重溫和記錄。
排查技術方向
服務器CPU高
- top
得到cpu占用高的pid
注意:這里判斷CPU利率用是否很高,不能只看PID是否超過100%,還應結合CPU核數
cat /proc/cpuinfo| grep "processor"| wc -l
PID cpu% < 100*cpu cores %不算是CPU利用率高
看第三行更直觀
- %Cpu(s): 36.5 us, 0.9 sy, 0.0 ni, 62.4 id, 0.0 wa, 0.0 hi, 0.2 si, 0.0 st
- top -Hp pid
得到該應用的所有子進程占用cpu情況
subpid1
subpid2
- printf '%x\n' subpid1
得到該進程的十六進制碼
如遇大寫轉小寫
如 A5DE 轉 a5de
- jstack pid | grep subpid1的十六進制碼
定位到代碼
- jstack pid 報錯
jstack Unable to open socket file: target process not responding or HotSpot
網上很多方案都是當前進程不是當前用戶所發起。切換了用戶依然不能執行。最后解決方案是:
切換到/tmp/hsperfdata_root
看是否有pid
如有,在此執行
總結
不一定能完全記住命令,但思路應該是很清晰的。
基本原理是
jstack pid 查看進程的堆棧信息
但是這是查看的全部,如果要查看該應用里占CPU高的具體進程的具體代碼得到篩選,做法就是將CPU高的子進程翻譯為十六進進制,再grep命令篩選
內存占用高
-
jmap -heap pid
查看堆棧信息 -
查看大對象
jmap -histo:live pid
輸出內容的一些說明:
[C is a char[]
[S is a short[]
[I is a int[]
[B is a byte[]
[[I is a int[][]
上面的輸出中[C對象占用Heap這么多,往往跟String有關,String其內部使用final char[]數組來保存數據的。
可以使用jmap把堆信息導出,並使用可視化工具mat分析。導出的命令如下:
- jmap -dump:live,format=b,file=a.dmp pid
Dumping heap to /Users/canglong/dev/test/a.dmp ...
Heap dump file created
下載到本地,再使用內存分析工具mat分析。
具體技術排查
- 使用top命令可以看到最大進程占用CPU達到1000+%
但總體cpu user 使用率為30+%。
服務器為32核,因此1000+的CPU使用剛好為30%左右。
正常。
- 使用top -Hp pid看到大量線程CPU使用率為70+
提取一個線程將之轉換為十六進制
printf "%X\n" 42455
A5D7 -> a5d7
使用jstack查看只包含該線程的堆棧信息
jstack pid | grep a5dc -C 10
可以看到占用CPU率高的代碼出處。經檢查,正常。
直接使用jastack查看公司包名關鍵字的信息
jstack pid | grep com.xxx
看到大量TIMED_WAITING(sleep),經排查,是使用sleep定時喚醒kafka的一個心跳任務。疑似正常。
- 查看大對象
jmap -histo:live pid| head -20
可以看到有一個自定義的對象達到30多個G。
再通過查看flink gc日志
發現大約每小時會有一次full gc.
疑似問題症結所在。