一、CPU

系统态
以前的一个案例,告警系统通知系统CPU使用率高,登录shell后执行top、vmstat、pidstat三个命令观察,首先发现是应用进程的CPU使用率高,可以确认是应用进程引起的,其次top发现CPU使用率集中在系统态。可能是系统内核或者系统调用的问题,常见的场景的是系统调用,上下文切换等,所以看了一下vmstat的上下文切换次数,对比其他服务器的进程,这个值非常大,但是有一个小插曲看pidstat发现上下文切换数值很少,后面查看帮助文档发现线程需要加-t参数,也说明了排查问题要多个工具对比查看。现在我们几乎可以确定是线程太多导致上下文频繁切换,从而引起CPU的升高,最后,我们可以去验证一下,在我们查看vmstat的时候,发现中断次数也比较多,从而我们去查询/proc/interrupts文件,使用watch -d动态查询,发现变化最快的重调度中断Res(rescheduling interrupts),和前面的结论一致。

处理:我们联系研发同学,说明相关问题,发现是研发同学在线上发布,新发布的一个节点配置线程有问题。后续回滚版本,我们也把us,cs,in指标采集,并配置了告警。

用户态
以前的一个案例,告警系统通知系统CPU使用率高,登录shell后执行top、vmstat、pidstat三个命令观察,首先发现是应用进程的CPU使用率高,可以确认是应用进程引起的,其次top发现CPU使用率集中在用户态。用户态CPU高,那么可以确认是进程的使用率高。Java应用的话,我们一般使用jstack查看线程堆栈,查看是否有死锁、死循环、等待外部资源的情况,定位发现是是gc导致的,同步jstat查看gc,发现Full GC比较多,先使用jmap打印内存映射,后面临时调整节点的内存解决,然后分析jmap发现是一个对象没有释放导致的,同步结论给研发进行优化。
C语言的程序,使用perf top或者pref record 查找进程的热点函数,分析对应的函数具体逻辑,当时遇到一个程序打印debug日志的情况,导致进程占用CPU 比较高。进一步可以使用火焰图去分析

案例二

研发修改业务框架后CPU明显上升,当时配合打印线程堆栈信息,但是研发没有排查出问题,采取最暴力的方式,扩容节点。后续我拉了基础技术团队、研发成员一起排查,因为这次框架变更业务还接入kafka,当时我建议研发先关闭kafka,先排除kafka的因素,保持唯一变量,这也是问题定位常用的一个原则,然后配合打印堆栈信息和线程CPU使用率信息,协助基础技术人员排查问题,一开始定位怀疑是日志开启了debug模式,但是当时查看日志的量和之前一样,没有很大的增加,然后又排除其他方向,但是也没有发现异常,最后还是回到日志的debug,查看配置文件,发现是日志配置ROOT级别配置了debug,但是内部配置了warn,根据最近优先原则,内部配置生效,所以打印日志不多,但是新框架还是会用到root级别的配置,调用一个对象AbstractLogger函数,这个函数是很消耗CPU的。最后,修改配置,CPU使用率降下来了,然后回收之前扩容的实例。

IO

以前的一个案例,告警系统通知IOwait的CPU使用率比较高,登录shell后执行top,vmstat,pidstat -d三个命令观察,首先top显示io wait cpu使用率超过90%,我们执行iostat -x -d 查看sda磁盘使用率接近100%。查看pidstat 看到是应用进程在大量写,可以确实是有用户进程引起的。(另外说一下,导致IO使用率高大概是两种情况,磁盘存在坏分区,可以使用smartctl查看,或者用户进程存在大量的读写),该案例是用户进程存在大量写情况,所以我们具体分析用户进程,我们使用strace命令查看进程的具体命令,发现进程在大量的写logtest文件,由此我们推断是进程在大量的写文件,我们可以使用lsof -p pid 继续查看,发现进程确实打开了logtest文件,由此确认是用户进程大量写日志引起的,查看代码,我们发现线上日志开启了info级别,导致大量的日志,和研发沟通,调整日志级别为warning。解决该问题

si
以前得一个案例,告警系统告警一个接口某个时间段经常504,然后在接下来得一天,登录shell,查看top,vmstat,pidstat,发现CPU整体使用率很低,进程使用率也很低。但是发现si使用率达到5%,进程种ksoftirqd进程使用率排在前面,怀疑是软中断得问题。然后我们观察/proc/softirqs文件,通过观察,发现net_RX变化最快,可能是网络原因,然后我们执行sar -n DEV 1观察网络确实有接收数据,然后看PPS比较大,但是每秒字节数比较小。我们继续使用tcpdump监听eth0网卡,发现大量得SYN包,结合前面得小包,我们推断是SYN FLOOD。接下来我们查看来源IP得负责人,发现是网络组同学,误配置导致攻击到线上运行得服务器,后续修改配置解决

hi

僵尸进程

以前的一个案例,排查问题的时候发现系统中有比较多的僵尸进程,僵尸进程的形成是因为子进程先于父进程退出,但是父进程没有正确处理子进程的退出,包括没有调用wait 或者waitpid,亦或是,没有注册SIGCHLD信号的处理函数。导致子进程退出没有被正确处理。
排查方式,首先通过pstree -asp 查看进程的父进程,然后查看父进程的代码,检查父进程处理子进程的地方,发现是wait()方法位置错误,导致父进程一直没有调用子进程。通知研发修改wait调用方式,问题解决

二、内存

进程内存

以前的一个案例,内存泄漏。因为遇见比较多的是java的内存泄露,以java为准,当时线上报警一个服务器的内存使用率过高,查看发现是进程使用的,首先查看jstt -gcutil 查看进程有正常的gc,但是内存整体使用量还是一直上升,怀疑是java内存泄露。
排查首先使用jmap -dump打印内存映射,使用MAT分析工具分析,优先查看长时间存活的对象、静态变量、集合对象。然后定位到泄露对象,分析其引用连确认无法回收的原因,查看对象是否被意外的保持了引用,包括未关闭的资源、缓存和监听器等。当时那个问题是一个集合对象有缓存,但是没有正确清理,导致缓存使用量一直增加
之前也关注过C语言的分析,可以使用bbc软件包的memleak工具

buffer

cache

以前的一个案例,告警系统通知系统内存使用率高,查看free命令,结合/proc/meminfo,发现cache使用率比较高,已知buffer是磁盘设备的缓存,而cache是文件系统的缓存。所以我们可以明确进程操作了大量的文件,然后通过pidstat -d发现了应用进程在大量读写,使用lsof -p pid ,看到进程在大量读写临时文件,联系研发排查,发现是每个功能点大量会创建删除文件。
针对该问题,我们临时采用了 echo 1 > /proc/sys/vm/drop_cache,后面研发同学优化这块逻辑,最终解决了问题

swap

三、文件系统和IO

文件系统
磁盘

inode

删除的文件没释放

IO

磁盘坏道

IO使用率高

四、网络

网线老化

数据链路层

网络层
MTU

ip_forward

传输层

端口范围不足

文件描述符不足

系统进程数不足

timeout过多

ddos攻击

套接字

backlog不足

#

五、应用层


协议不匹配
线程数不足

iptables

conntrack不足