目录
- 问题描述
- 排查技术方向
- 服务器CPU高
- 内存占用高
- 具体技术排查
问题描述
flink+kafka,某些时候会有消息规程,量不大,但缓慢上升。
初步排查:
kafka集群正常,消息接入,节点,内存,CPU均正常。
宽带正常。
flink反压正常。
--本文问题由flink+kafka引出,但与kafka和flink技术本身无关。
--本文主要记录内存CPU高的解决思路做一次重温和记录。
排查技术方向
服务器CPU高
- top
得到cpu占用高的pid
注意:这里判断CPU利率用是否很高,不能只看PID是否超过100%,还应结合CPU核数
cat /proc/cpuinfo| grep "processor"| wc -lPID 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.
疑似问题症结所在。
苍茫之天涯,乃吾辈之所爱也;浩瀚之程序,亦吾之所爱也,然则何时而爱耶?必曰:先天下之忧而忧,后天下之爱而爱也!