整理和总结一些Linux后台开发常用分析工具和问题排查思路,主要包括CPU、内存、磁盘、网络四个方面,并归纳成思维导图方便记忆和查询。

分析工具

Linux有很多性能分析工具, 下面的思维导图总结了一些常用工具.

Linux性能分析工具和方法总结

分析方法

Linux上的问题排查是后台开发的家常便饭,有时候查个问题不知从何下手,甚至要花费一两天时间,所以能尽快的缩小问题范围和定位问题根源,不给产品大大拖后腿,是所有开发的愿景。

我根据以前的笔记整理了排查问题的思路图,希望能提供一些解决问题的思路。按下图走到叶子节点的时候可能没有想要的解,但也可能帮助缩小了问题范围和获得了相关信息,方便网上查询和咨询他人。图中的意思不是指从CPU --> 内存 --> 磁盘 --> 网络依次排查,如果能明确的确定哪方面有问题,直接从该问题类型开始往下排查。

Linux性能分析工具和方法总结

下面的内容是对上图进行展开,通过标题号对应。

1 CPU使用有问题?

使用top等命令查看CPU使用率和负载是否过高。

1.1 内核空间占用了大多数CPU

通过top命令查看内核占用CPU比例是否过大。

1.2 内核处理了很多中断吗?

使用procinfo或cat /proc/interrupts查看中断次数和频率,以及造成中断数量较高的设备。

1.3 内核的时间花在哪了?

使用oprofile分析哪些内核函数消耗大量时间,并查询这些函数的功能,确定它们处于哪个子系统(内存、网络、磁盘等)并了解可能被调用的原因。如果这些函数是设备特定的,尝试着找出为什么需要使用这种特定的设备(尤其是在1.2中造成高中断的设备),或许就可以判断出哪里出了问题。

1.4 用户空间占了大多是CPU?

通过top命令查看用户态是否占了大量CPU。

1.5 哪个进程占用了大多数CPU?

通过top命令进程排序列表确定占用大量CPU的进程。

1.6 进程在内核还是用户空间花费了时间?

使用time命令查看进程在内核和用户空间花费的时间,这里不一定非得任意一方非得占大多数时间。如进程在内核占用超过25%以上的时间,说明内核也排查是重点。

1.7 进程在哪些系统调用上花费了较多时间?

使用strace/oprofile查看进程调用了哪些系统调用和找出主要耗时时长的系统调用,通过减少系统调用次数或者更改性能更好的系统调用来提升性能。

1.8 进程在哪些函数上花费了时间?

使用ltrace/oprofile确定哪些函数消耗了大多数时间。如果函数调用次数过多,则检查是否存在不必要的调用次数,如for循环判断条件里不断调用某个函数或者debug日志里调某个函数得到一个字符串序列。如果单次调用就已经很耗时,使用oprofile/cachegrind分析函数是否存在热点代码大量cache缺失,通过调整数据结构或调整代码提高热点代码cache命中。

2 内存使用有问题?

通过top/vmstat/procinfo等确定内存使用是否过高,内存交换空间不断增加。

2.1 内核使用内存在增加?

使用slabtop查看内核使用内存是否增加或者使用量过大。

2.2 内核使用的内存类型是什么?

使用slabtop排序内核使用内存情况,找出使用内存较大的对象名字。通过搜索或查询相关分配对象名字(如inode_cache),确定它用于哪些文件或属于哪个子系统,就有可能弄清楚内存分配的原因。

2.3 进程使用内存在增加?

使用top/ps按内存使用量排序并观察rss等字段看进程使用物理内存是否增加。

2.3.1 进程使用的内存类型是什么?

通过/proc//status查看内存使用情况。如VmExe值很大,则说明可执行文件本身很大,需要确定哪些函数文本比较大。VmLib很大,则说明应用程序使用了大量或者体积比较大的共享库,需要确定哪些库导致了VmLib很大。VmData较大并在增加,说明进程的数据区或堆在增加。

2.3.2 哪些函数使用大量的栈空间?

使用gdb attach进程,根据调用栈信息计算当前栈指针和前一个栈指针的差值,这个差值即为函数的栈容量,找到栈容量比较大的函数。

2.3.3 哪些函数分配大量的堆内存?

使用memprof找到哪些函数分配了堆内存并观察哪些进程的堆内存在增加,确定是否存在不合理的分配或者内存泄漏问题。

2.3.4 哪些库比较大?

通过/proc//maps查看进程使用了哪些共享库和以及这些库的大小,对于太大的共享库是否可能替换成大小更小的版本。或者某个库已经被其他进程加载到内存使用,只是版本不同,则可以改成共用一个版本。

2.3.5 哪些函数文本较大?

如果进程的可执行文件本身比较大,加载到内存后会占用更多的空间。可以通过nm命令排序符号大小,找出文本段较大的函数看是否可以删除或者减小其大小。

2.3.6 共享内存使用量在增加?

使用ipcs查看共享内存信息,是否存在过大或者共享内存数量不断增加。

2.3.7 哪个进程在使用共享内存?

使用ipcs -p查看哪些进程创建和使用了共享内存。对于共享内存过大问题,可以查看其程序代码看分配是否合理。对于共享内存数不断增加,是否存在创建后未删除等问题。

3 磁盘I/O使用有问题?

运行iostat,查看await平均等待时间,await越高则说明磁盘负荷越大。

3.1 哪个进程访问了磁盘?

通过iotop找到产生大量IO的进程。

3.2 进程访问了哪些文件?

通过strace跟踪高IO进程与文件操作相关的系统调用,查看其调用详情和耗时时长,找到耗时长的读写操作。并通过其操作的文件描述符fd映射回磁盘上的文件,了解为什么需要读写这些文件,进而查看是否可以优化。

4 网络I/O使用有问题?

使用ethool查看网卡的最大流量限制 ,并通过iptraf查看流经端口的流量是否饱和。

4.1 网络设备产生了大量错误?

使用ifconfig/ip命令查看网络接口是否产生大量错误,如果是可能是硬件配置的有问题,联系网管帮忙排查解决。

4.2 网络设备存流量类型是什么?

使用iptraf查看流量类型(协议/端口号)。

4.3 是否有进程处理该类型的流量?

使用netstat查看是否有进程在流经该网络端口的流量。

4.4 哪个远程系统发送了流量?

如果没有指定进程在处理这个流量,可能来自网络上其他系统的流量攻击。可使用etherape/wireshark尝试跟踪或者找网管咨询。

4.5 哪个套接字在处理流量?

在确定了处理流量的进程后,使用strace/lsof找到是哪个套接字产生了这些通信流量。

相关文章: