-
Notifications
You must be signed in to change notification settings - Fork 6
网站 CPU 占用过高原因排查 #105
Description
症状描述
有一天忽然发现公司的各个网站都打开很慢,登录阿里云控制台,发现 CPU 占用持续在 100%,其他资源占用都处于正常水平。
问题排查
找出占用 CPU 的程序
通过 Windows 远程桌面登录至云服务器,查看任务管理器,发现是 IIS Worker Process 这个进程把 CPU 占满了。
再运行 Process Explorer,查看 CPU 占用,发现是一个 w3wp.exe 占用了大量 CPU 资源,并且该进程开启了多个 PHP 线程。鼠标悬浮至该进程名称上,确认为公司一个业务网站所对应的 IIS 进程。
在 IIS 管理器中将该网站停止,然后在 Process Explorer 中再将其所对应的进程中止,CPU 占用立刻恢复至正常水平。
之后再将该网站运行起来并持续观察,发现该网站的 CPU 占用再次逐渐升高,可以确定就是该网站下的程序导致 CPU 占用过高。
查看 CPU 变化规律
持续观察该网站的运行情况,发现是在 CPU 占用正常一段时间之后就会逐渐升高,并有一段时间稳定在 50% 左右的水平;之后继续升高并稳定在 100% 数分钟。
在阿里云的云监控页面,逐天查看 CPU 使用率的历史数据,发现在近 7 天内,只有今天出现了这种情况。
更准确地来说,早上 8:30 左右 CPU 占用短暂地升到了 90% 附近,09:01-09:08、09:40-09:52、10:11-10:21,这三个时间段 CPU 占用都飙到了 100%。之后又有几次非常短暂地上升到 50%,但都很快又降下来了。
查看带宽变化
查看这一天上午的服务器带宽使用情况,发现除了 07:03 这个时刻有 800K 的入站峰值带宽,08:12 这个时刻有 32M 的出站峰值带宽,其余时刻都很正常。这样的出站带宽和入站带宽,和平时一样,所以排除带宽方面的原因。
查看进程及线程 CPU 占用
虽然是 w3wp.exe 这个进程的 CPU 占用高,但是它所开启的多个 PHP 的线程 CPU 占用是非常低的。而这个网站包含两部分:一部分是用 ASP 写的 PC 端的网站,另一部分是用 PHP 写的移动端的网站,莫非问题出在 PC 端页面上?
排查异常请求
查看阿里云 WAF 的安全报表,发现在几次 CPU 占用过高的时间点附近,并没有什么攻击记录。倒是 IIS 日志中有一些异常请求被记录下来了,但无法确定是不是这些请求导致的 CPU 占用过高。
查看请求耗时
将该网站上午的 IIS 日志进行分析,并与另一个访问量相当的网站进行对比。
另一个网站前一天所记录的 HTTP 请求中,响应时间超过 5 秒的几乎都是音频文件,并且最长也没超过 50 秒。
而 CPU 占用过高的这个网站,响应时间最长的能有 4 分钟。但是有一点无法确定,就是异常请求与 CPU 占用过高,两者谁是因谁是果,还是两者之间并无关系。
在排查过程中,发现 site\thinkphp\examt\Runtime\Logs\Home\ 这个路径下保存了一个 PHP 程序的运行日志,先记下来,后面可能会用到。
查看网站当前连接
需要在服务器管理器中,开启 Web 服务器(IIS) → Web 服务器 → 运行状况和诊断 → 请求监视器 这个功能。但是开启这项功能的话,需要重启服务器,所以暂时没法使用这个方法来查看是什么连接导致 CPU 占用过高的。
- 关键字:
how to see current iis requests - How to access Request Monitor in IIS Server Manager?
- Check incoming requests IIS with Request Monitor
分析 IIS 日志
将当日的 CPU 使用率曲线,与 IIS 日志中响应时间超过 10 秒的请求进行对比,比较可疑的就是前面说的异常请求。具体来说,是一个特殊的 URL 查询字符串,在出现该查询字符串的时候,尤其是短时间多次出现的时候,CPU 使用率就很高。
为了复现该问题,在浏览器的隐私模式中开了 8 个标签页,同时开启开发者工具并选择跳过缓存。访问指定网站时均附带上这个特殊的查询字符串。
观察对应网站进程 CPU 使用率及整体 CPU 使用率,发现网站进程 CPU 使用率达 90% 多,整体 CPU 使用率则基本上都在 100%。
在不同时间、不同的电脑上用浏览器测试,均能够复现该现象,说明应该就是这个特殊的查询字符串导致 CPU 占用过高。
另外经过在不同的网站上测试对比,发现该查询字符串只对用 ASP 编写并放在网站根目录下的站点有效,如果是用 ASP 编写但没有放在根目录下,该查询字符串也无效。对于不是用 ASP 编写的网站同样无效。
屏蔽非法请求
23:47 的时候,在 IIS 中对匹配该查询字符串开头 3 个字符的 HTTP 请求一律屏蔽。
同时将阿里云记录的这一天的 CPU 使用率,以小时为单位,都进行了截图,以便第二天对比效果。
限制网站 CPU 用量
具体操作见 限制网站硬件资源用量。
后续跟进
在 IIS 中限制了该网站的 CPU 使用率,以及屏蔽了指定 HTTP 请求之后,CPU 使用率就一直维持在正常水平了,而且这个特殊请求也没有再出现,这个问题算是告一段落。