阿里云ECS的CPU100%排查

作者:一夕如环 来源:https://www.cnblogs.com/hodge01/p/8658538.html一、背景和现象
初创公司,架构lanmp,web前端和后端分开服务器,业务驱动主要是Nginx和Apache,nginx主要是处理静态文件和反向代理,前后端、搜索引擎、缓存、队列等附加的服务都是用Docker容器部署 。因为比较初级,上传文件和采集文件都是直接写在硬盘上,涉及到的目录共享,就在其中一台服务器存储并且nfs共享 。我们暂且分为ECS1(apache1)、ECS2(apache2)、ECS3(nginx) 。某天网站业务中断,但是没有报错 。一直在等待响应,默认响应超时是一分钟,所以很基础高可用没有起到作用 。中断10分钟左右,重启服务,提示“open too many files”,但是lsof统计没几个 。因为初级处理不了,所以直接重启服务器,一段时间后一切恢复正常,可是第二天又来一次这种情况 。
二、第一次出现后的排查思路
本来第一次发现这种问题的时候就要追查原因了,看了一下zabbix监控图像其中断了十分钟,包括网络、内存、CPU、硬盘、IO等监控数据 。首先想到的是网络问题,结论是zabbix-servert获取不到了zabbix-agent采集的数据,估计就是网络不通了 。

阿里云ECS的CPU100%排查

文章插图
 
但是,这个结论站不住脚,因为我本身通过ssh登录服务器,并且命令输入无卡顿,不至于头文件都传不过来 。后来一看阿里云的云监控,上面有数据,似乎也可以佐证网络这个说法,因为云监控是阿里云内部的监控,可以内网获取到监控数据 。直到看CPU的使用率这项,发现有一段时间的CPU使用率100% 。并且我重启的时候CPU恢复正常,不能说网络一定没问题,但系统肯定有问题 。也可以解释因为CPU使用已经是100%,zabbix-agent和根本不能正常运行,所以没有监控数据 。因为这个公司全部都是云服务器,没有使用IDC所以我们也没有安装smokeping来监控,接着我们就不把重心在网络上了 。
目前掌握的信息就是:在毫无征兆的情况下,CPU暴涨到100%,重启之前一直保留,重启之后恢复原样 。匆忙之中又看了一下系统各日志,因为太匆忙,没有总结,没有找到什么有价值的东西 。现在有下面几种猜想:第一,程序的bug或者部署不当,触发之后耗尽资源 。第二、docker容器的bug 。第三、网络攻击 。第四、病毒入侵 。第五、阿里云方系统不稳定 。
小总结了一下,现在问题还没有找出来 。下次还有这个问题的可能,所以先尽量防范,但是又不能重启一刀切 。所以在zabbix上面设置了自动化,当检测到ECS1获取不到数据的时候马上操作ECS3标记后端为ECS1的apache为down 。保留异常现场 。(请求停止的时候,CPU100%还在)
三、现场排查
1、相应的排查计划(想到这些信息需要获取的,实际上没有严格按照这样的步骤)
1)用htop和top命令监控CPU、内存使用大的进程 。先看看哪个进程消耗资源较多,用户态、内核态、内存、IO……同时sar -b查io的历史定时抽样 。
2)统计tcp连接数,看看有没有DDoS攻击 。netstat -anp |grep tcp |wc -l。用iftop-i eth1看看通讯 。同时用tail -n 1200 /var/log/messages查看内核日志 。
3)用pstree查看打开进程,ps aux|wc-l看看有没有特别多的进程 。虽然zabbix监控上说没有,但是我们要检查一下看看有没有异常的进程名字 。
4)查看全部容器的资源使用docker stats $(docker ps -a -q),看看能不能从容器上排查 。
5)有了“too many open files”的启发,计算打开文件数目lsof|wc -l,根据进程看看ll /proc/PID/fd文件描述符有没有可疑的打开文件、文件描述符 。
6)关于用lsof打开文件数找到的线索,排序打开文件找出进程号 lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|more
7)关于用lsof打开文件数找到的线索,用lsof -p PID查看进程打开的句柄 。直接查看打开的文件 。
8)启动容器的时候又总是“open too many files" 。那就是打开文件数的问题,因为CPU的使用率是CPU的使用时间和空闲时间比,有可能因为打开文件数阻塞而导致CPU都在等待 。针对连接数的问题,大不了最后一步试试echo 6553500 > /proc/sys/fs/file-max 测试打开文件对CPU的影响 。
9)玩意测出来了消耗CPU的进程,可以使用strace最终程序 。用户态的函数调用跟踪用「ltrace」,所以这里我们应该用「strace」-p PID
10)从程序里面看到调用系统底层的函数可以跟踪 。跟踪操作 strace -T -e * -p PID,主要看看代码调用的函数有没有问题 。


推荐阅读