阿里云ECS的CPU100%排查( 二 )


2、现场排查
第二天同样时间,ECS果然暴涨了CPU 。这是时候zabbix的工作如希望进行保留了一台故障的ECS1给我 。
1)用htop看到资源使用最大是,搜索引擎下我写的一个判断脚本xunsearch.sh 。脚本里面很简单,判断索引和搜索服务缺一个就全部重启 。就当是我的容器有问题我直接关掉搜索引擎容器 。httpd顶上,我又关掉apache容器 。rabbitmq相关进程又顶上 。这时候我没心情周旋了,肯定不也是这个原因 。sar -b查看的历史io也没有异常 。

阿里云ECS的CPU100%排查

文章插图
 
2)统计tcp连接,几百 。先不用着重考虑攻击了 。用tail -n 1200 /var/log/messages查看内核日志,是TCP TIME WAIT的错误 。可以理解为CPU使用100%,程序无响应外面的tcp请求超时 。这是结果,还是没有找到根本原因 。
阿里云ECS的CPU100%排查

文章插图
 
接着往下看系统内核日志,发现了和“open too many files”呼应的错误,“file-max limit 65535 reached”意思是,已到达了文件限制瓶颈 。这里保持怀疑,继续收集其他信息 。
阿里云ECS的CPU100%排查

文章插图
 
3)查看进程数量,数量几百 。列出来也看到都是熟悉的进程,可以先排除异常进程 。
阿里云ECS的CPU100%排查

文章插图
 
4)监控容器的资源使用,里面很不稳定,首先是xunsearch容器使用80%的CPU,关掉xunsearch,又变成了其他容器使用CPU最高 。很大程度上可以排查容器的问题和执行程序的问题 。
5)查看了最大连接数cat /proc/sys/fs/file-max是65535但是用lsof查到的连接数是10000多,完全没有达到连接数 。
6)各项参数都正常,现在聚焦在打开的文件数这个问题上面 。也可以用另外同一种方式查看一下内核统计文件 /proc/sys/fs/file-nr,比较一下差异,看看能不能找出问题 。cat了一下,打开文件数是66080,果然超了!内核日志就以这个为标准 。
阿里云ECS的CPU100%排查

文章插图
 
但是看lsof怎么统计不出来,ll /proc/PID/fd也没几个 。这个问题放在后面,先按照步骤echo 6553500 > /proc/sys/fs/file-max给连接数提高到100倍,CPU果然降了下来 。原因确认了,但是必须找到根源,为什么忽然有这么大的打开文件数 。关掉全部docker容器和docker引擎,打开文件数是少了一点,但是仍然在65535差不多 。我就先排除一下业务的影响,把ECS3的nginx直接指向视频ECS2的apache,就等同于在ECS2上实现了ECS1的场景 。查看一下ECS2的句柄数,才4000多,排除了业务相关应用对服务器的影响 。那就能下个小结论,ECS1被神秘程序打开了6万多句柄数,打开业务就多了2000多的句柄数,然后就崩溃了 。不过这个现象有点奇怪,ECS2和ECS1在一样的机房一样的配置一样的网络环境,一样的操作系统,一样的服务,一样的容器,为什么一个有问题,一个没问题呢?不同的只是有一台是共享nfs 。难道是静态文件共享了,其他人读了,也算是本服务器打开的?
7)现在程序找不到,没法继续lsof -p了 。排查之前的猜想 。带着排查得到对的结论往下想 。
程序的bug和部署不当,那是不可能的,因为主要问题来自于打开句柄数,当部署到ECS2那里,一切正常 。docker容器的bug,那也不可能的,每个都是我亲自写脚本,亲自编译,亲自构建的,关键是我关掉了docker容器和引擎都没有很大改善 。网络攻击也排除,因为网络连接数没几个,流量也不变 。那就只剩下病毒入侵也不是,没有异常进程 。考虑到ECS的稳定性问题了 。这方面就协助阿里云工程师去排查 。
阿里云ECS的CPU100%排查

文章插图
 
8)阿里云工程师用的排查手段和我差不多,最终也是没能看到什么 。也只是给了我一些治标不治本的建议 。后来上升到专家排查,专家直接在阿里云后端抓取了coredump文件分析打开的文件是图片,程序是nfsd 。
阿里云ECS的CPU100%排查

文章插图
 
好像印证了我刚才后面的猜想,应该就是ECS1使用了nfs共享其他服务器打开了然后算在ECS1头上 。那问题又来了,我们的业务已经到达了可以影响服务器的程度吗?
9)既然问题解决到这一步,先不管程序有没有关闭打开的文件和nfs的配置 。我们架构上面的图片应该是归nginx读取,难道是linux的内存机制让它缓存了 。带着缓存的问题,首先去ECS3上释放内存echo 3 > /proc/sys/vm/drop_caches,释放之后,发现没什么改善,有点失落 。总是觉得还有一台后端是php主导,但是逻辑上是写入,没有打开文件之说 。后来从程序员中了解到,PHP也有打开图片 。我猛然去ECS2释放一下内存,果然,句柄数降下来 。(这里大家一定有个疑问,为什么我直接想到内存缓存而不是目前打开的文件呢 。其一,这是生产环境,web前端只有一个,不能乱来停服务 。其二,第一次遇到问题的时候,重启之后没有问题,过了一天之后积累到一定的程度才爆发,这里已经引导了我的思路是积累的问题,那就是缓存不断积累了)


推荐阅读