本系列主要是充分使用eBPF来延时如何定位实际问题,在生产中碰到类似问题也可以采用文中所描述方法。
先编译源码,代码下载位置:
https://github.com/kernel-z/linux-tracing-workshop/blob/master/server.c
代码就是模拟一个应用启动,启动过程会去读取配置文件,如果没有配置文件会循环一直去读永不止息,这个是为了演示方便(实际应用会退出并提示相关错误的)。
# gcc -g -fno-omit-frame-pointer -O0 server.c -o server
其中参数-fno-omit-frame-pointer,O0表示取消栈和相关代码编译优化。
然后执行./server
1. 基本诊断
发现系统卡主了,用top命令查看该进程还占用一定的CPU资源。
然后使用pidstat来查看进程每秒用户和系统资源情况。
# pidstat -u -p $(pidof server) 1
21时34分27秒 UID PID %usr %system %guest %CPU CPU Command
21时34分28秒 0 2654 5.13 14.10 0.00 19.23 0 server
21时34分29秒 0 2654 5.13 15.38 0.00 20.51 0 server
其中-u表示显示CPU使用率,另外从监控数据可以看到CPU使用率是位于内核系统。
既然在内核态,那么程序肯定调用了大量的系统调用。使用bcc的syscount工具。
2. 内核态挖掘
既然在内核态,那么程序肯定调用了大量的系统调用。使用bcc的syscount工具。
# ./syscount.py -p $(pidof server)
输出如下:
Tracing syscalls, printing top 10... Ctrl+C to quit.
^C[21:44:08]
SYSCALL COUNT
open 52400
nanosleep 52400
看主要是open系统调用。
3. 跟踪系统调用
使用opensnoop工具,调用如下:
#./opensnoop.py -p $(pidof server)
……
2654 server -1 2 /etc/tracing-server-example.conf
……
发现做打开的目的文件了,返回的错误为-1,表示文件找不到。
至此,问题已非常明确。