本篇文章4551字,读完约11分钟
一、背景和现象
初创公司、lanmp架构、web前端和后端分开的服务器,业务驱动程序主要是nginx和apache,nginx主要处理静态文件和反向代理,而前端和后端、搜索引擎、缓存和队列等附加服务由docker container部署。因为它是相对简单的,上传文件和收集文件是直接写在硬盘上的,并且涉及的目录共享存储在一个服务器上,由nfs共享。我们暂时分为ecs1(apache1)、ecs2(apache2)和ecs3(nginx)。一天,网站业务被中断,但没有错误报告。我一直在等待响应,默认的响应超时是一分钟,所以基本上高可用性不起作用。中断约10分钟,重新启动服务,并提示“opentoomanyfiles”,但几乎没有lsof统计数据。由于主进程无法完成,服务器被直接重启,一段时间后一切恢复正常,但第二天又发生了这种情况。
最初,当我们第一次发现这种问题时,我们不得不追查原因。在查看了zabbix监控图像后,它被破坏了十分钟,包括网络、内存、cpu、硬盘、io和其他监控数据。首先想到的是网络问题。结论是zab bix-server无法获取zabbix-agent收集的数据,估计网络被阻塞。
然而,这个结论是站不住脚的,因为我通过ssh登录到服务器,并且命令输入没有被阻塞,所以头文件不能被传输。后来,当我看阿里巴巴云的云监控时,上面有数据,似乎支持网络的说法,因为云监控是阿里巴巴云的内部监控,监控数据可以从内部网获取。直到我们看到cpu利用率,我们发现在一段时间内cpu利用率是100%。当我重启时,中央处理器恢复正常。我不能说网络一定没有问题,但系统一定有问题。这也可以解释为什么没有监控数据,因为cpu使用率已经是100%,而zabbix-agent根本无法正常工作。因为这家公司都是云服务器,我们不使用idc,所以我们不安装烟雾监控,然后我们不关注网络。
目前,我们所知道的信息是:在没有任何警告的情况下,中央处理器已经飙升到100%,在重启前一直保持,重启后又恢复到原来的状态。匆忙中,我又看了一遍系统的日志,因为我很匆忙,没有总结,也没有发现任何有价值的东西。现在有以下推测:第一,程序的错误或不当部署在触发后耗尽了资源。第二,码头工人集装箱错误。第三,网络攻击。第四,病毒入侵。第五,阿里巴巴云系统不稳定。
经过简短的总结,问题还没有被发现。下次可能会有这个问题,所以先试着防止它,但是你不能全面地重新开始。因此,在zabbix上设置了自动化,当检测到ecs1无法获取数据时,ecs3立即运行,将带有ecs1的apache标记为关闭。保留异常场景。(请求停止时,中央处理器仍为100%)
1.相应的故障排除计划(认为需要获得此信息,事实上,此类步骤并未严格遵循)
1)使用htop和top命令监控cpu和内存使用量大的进程。让我们先看看哪个进程消耗更多的资源,比如用户模式、内核模式、内存、io……同时,sar-b检查io的历史定时采样。
2)计算tcp连接数,看是否有ddos攻击。netstat-anp|greptcp|wc-l .检查与iftop-ieth1的通信。同时,使用tail-n1200/var/log/messages查看内核日志。
3)使用pstree查看打开的流程,使用psaux|wc-l查看是否有任何特殊流程。虽然zabbix监控说没有,但是我们应该检查是否有任何异常的进程名。
4)检查所有容器的资源,并使用dockerstats$(dockerps-a-q)查看是否可以从容器中进行检查。
5)受“toomanyopenfiles”的启发,计算打开文件lsof|wc-l的数量,并根据流程检查ll/proc/pid/fd文件描述符中是否有可疑的打开文件和文件描述符。
6)对于由lsof打开的文件数量所发现的线索,对打开的文件进行排序,并找出lsof-n | awk & # 39;{打印$ 2 } & # 39;| sort | uniq-c | sort-NR |更多
7)关于通过使用lsof打开的文件数量找到的线索,请检查由使用lsof-ppid的进程打开的句柄。直接查看打开的文件。
8)启动容器时,总是“打开太多文件”。这就是打开文件数量的问题,因为cpu利用率是cpu使用时间与空空闲时间的比率,这可能会导致cpu等待,因为打开文件的数量被阻止。对于连接数的问题,尝试echo 6553500作为最后一步>:/proc/sys/fs/file-max测试打开文件对cpu的影响。
9)这个小工具检测消耗cpu的进程,因此可以使用strace最终程序。用户模式函数调用跟踪使用“ltrace”,所以我们应该在这里使用“strace”-ppid
10)从程序内部,您可以看到系统底部的函数调用可以被跟踪。跟踪操作strace-t-e*-ppid,主要是看代码调用的函数是否有问题。
2.现场调查
第二天的同一时间,ecs真的跳过了cpu。如果zabbix想为我保留一个有缺陷的ecs1,那么他的工作该开始了。
1)使用htop,我们可以看到最大的资源使用是我在搜索引擎下写的一个判断脚本xunsearch.sh。脚本非常简单,判断索引和搜索服务丢失,它们都将重新启动。假设我的容器有问题。我会关掉搜索引擎容器。在httpd之上,我再次关闭了apache容器。拉比姆克相关的过程又一次处于领先地位。那时,我没有心情到处玩,这肯定不是原因。sar-b观测到的历史io没有异常..
2)计算tcp连接,数百个。我们不要把注意力集中在攻击上。查看带有tail-n1200/var/log/messages的内核日志是tcptimewait的一个错误。可以理解,中央处理器是100%使用,程序是无反应的。外部的tcp请求超时。这是结果,或者根本原因还没有找到。
然后向下看系统内核日志,我发现了一个对应于“opentoomanyfiles”的错误。“file-maxlimit 65535 reach”表示已达到文件限制瓶颈。把你的疑问留在这里,继续收集其他信息。
3)检查进程的数量,它是几百个。您还可以看到列出的所有流程都很熟悉,因此您可以首先排除异常流程。
4)监控容器的资源使用不稳定。首先,寻搜索容器使用80%的cpu,寻搜索被关闭,其他容器使用cpu。在很大程度上,它可以解决容器的问题和执行程序的问题。
5)检查最大连接数cat/proc/sys/fs/file-max是否为65535,但lsof发现的连接数超过10000,这根本达不到连接数。
6)所有参数都正常,所以现在关注打开文件的数量。您也可以用同样的方式查看内核统计文件/proc/sys/fs/file-nr,比较它们之间的差异,看看是否能找出问题。猫了一下,打开的文件数是66080,这真的结束了!这是内核日志的标准。
然而,很少有ll/proc/pid/fd。把这个问题放在后面,首先按照步骤echo 6553500 >:/proc/sys/fs/file-max将连接数增加到100倍,cpu真的下降了。原因已经确定,但必须找到根本原因。为什么突然有这么多打开的文件?关闭所有码头工人容器和码头工人引擎,打开的文件数量会少一点,但仍然是65535。我将首先排除业务的影响,将ecs3的nginx直接指向视频ecs2的apache相当于在ecs2上实现ecs1的场景。从ecs2中的句柄数量来看,它只有4000多个,这排除了业务相关应用程序对服务器的影响。然后我们可以得出一个小结论。ecs1是由一个拥有超过60,000个句柄的神秘程序打开的,它用超过2,000个句柄打开了业务,然后崩溃了。然而,这种现象有点奇怪。ecs2和ECCS1配置有相同的网络环境、相同的操作系统、相同的服务和同一计算机房中的相同容器。为什么一个有问题,而另一个没有问题?唯一的区别是一个是共享的nfs。静态文件是共享的吗,其他人读了,这可以看作是打开了这个服务器吗?
7)现在程序找不到它,所以它不能继续LSOF-P。检查以前的猜测。认为调查是正确的结论。
程序的Bug和不适当的部署是不可能的,因为主要问题来自打开的句柄的数量。当部署到ecs2时,一切正常。码头工人集装箱里的虫子,那是不可能的。我编写脚本,编译并构建每一个。关键的一点是,我关闭了码头集装箱和引擎,但它没有改善多少。网络攻击也被排除在外,因为网络连接很少,流量也不变。那么只有病毒入侵没有留下,也没有异常过程。考虑到ecs的稳定性。在这方面,我们将协助阿里巴巴云工程师进行调查。
8)阿里巴巴云的工程师和我使用了类似的筛选方法,但他们最终什么也没看到。它只是给了我一些治标不治本的建议。后来,它上升到专家调查,专家直接在阿里巴巴云的后端抓取了核心转储文件。打开的文件是图片,程序是nfsd。
这似乎证实了我刚才的猜测,即ecs1使用nfs进行共享,其他服务器被打开,然后依靠ECS1。那个问题又来了。我们的业务是否达到了会影响服务器的水平?
9)既然问题已经解决到这一点,不管程序是否已经关闭了打开的文件和nfs配置。我们的建筑上方的图片应该由nginx阅读。是因为linux的内存机制才被缓存的吗?关于缓存的问题,首先去ecs3释放内存echo 3 >:/proc/sys/VM/drop _ cache,在释放后,发现没有改进,有一点损失。我总觉得还有另一个由php主导的后端,但是从逻辑上来说,它是被编写的,没有打开文件的说法。后来,我从程序员那里得知php也有开放图片。我突然去ecs2释放内存,果然,句柄的数量下降了。(这里一定有一个问题,为什么我会直接想到内存缓存,而不是当前打开的文件?首先,这是一个生产环境,并且只有一个web前端,所以您不能不加区别地停止服务。第二,当我第一次遇到问题时,重启后没有问题。一天之后,它积累到一定程度才爆发。在这里,我已经引导我思考的是积累的问题,也就是说,缓存一直在不断积累。(
10)因为ecs2调用ecs1的nfs共享文件,lsof也有它不能读取这么多句柄的原因。如果nfs服务本身有缓存,这就导致了问题,我检查了配置文件,但是默认值允许缓存,30s过期,这不会因为nfs缓存而导致打开太多文件。如果我们的后端程序在打开后处理不当,这是可能的。然后尝试消除它:我改变了ecs3的配置,这样程序只读取ecs1的后端,但ecs1没有异常性能,这表明php程序很好地处理了打开的文件。docker挂载nfs共享不是问题,因为nginx也被挂载了。这也在很大程度上解决了这个问题,nfs的所有共享文件都被缓存了,并且句柄没有增加,这是合理的,所以打开文件的数量限制增加了。
11)现在,故障排除的结果与后端和nfs共享有关。也就是说,nfs的网络共享安装在后端,由程序读取。程序发布后,正常背景下的硬盘文件不会被缓存。但是,在nfs装载环境中,缓存尚未释放。
12)总结:排除许多问题的结果与我们的猜测相同,但也有一些例外。例如,我这次想到的所有原因都一一消除了,但问题是在调查中逐步发现的。
标题:阿里云 ECS 的 CPU 100% 排查
地址:http://www.hcsbodzyz.com/hcxw/564.html