什么可能导致一个Apache服务器locking“发送回复”进程?

我正在运行一个CentOS服务器作为一个LAMP栈服务于一个自定义的PHP应用程序。 看起来随机的时间间隔会减慢。 查看服务器状态页面,我看到PID列表被locking了几个相同的Ajax调用所有请求从一个用户的客户端IP。 (知识产权的变化,但总是只有一个)

我看到"Sending Reply"的“M”参数状态是W,这是什么意思?

缓慢通常在5分钟到1小时后自行解决。 然而,有一天我决定执行:

 service httpd restart graceful. 

这完全解决了问题 – 10分钟。 下面是14分钟后的服务器状态,缓慢并locking。 看来这些请求很快就会build立到50,服务器变慢。

要考虑的要点:

  • 多个请求始终来自同一个IP
  • 请求持续约200秒的最大时间(SS)
  • 所有的请求都去一个ajax.php脚本
  • 减速有时不会发生几个星期,然后在几天内发生几次
  • 用户只能在服务器地址的浏览器中打开几个标签〜总共25个
  • 显然最糟糕的问题发生在下午晚些时候

在这里输入图像说明

所以我的问题是什么可能会导致此locking,为什么所有请求"Sending Reply"

这里是httpd.conf

 <IfModule worker.c> StartServers 2 MaxClients 50 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 MaxRequestsPerChild 0 </IfModule> 

看起来这些连接被卡住了很长一段时间(SS是请求的时间,其中一些正在推动几分钟)。

我的直觉告诉我看看数据库和PHP应用程序。 检查以便在池中有足够的可用连接,检查维护任务(完全真空可以长时间locking数据库!)并logging长查询,看看是否正在执行可能会locking重要表的操作。 PHP脚本中的问题也可能会阻止它及时终止。

这里是一个页面,提供了一些有用的debugging技巧,用于这种情况。

鉴于你的情况下,连接来自你的局域网,这不太可能是一个攻击,但在我的情况下,我有一个外部IP(在同一时间)在一个WordPress站点上做同样的事情(最新),得到这个,甚至东西像:

/wp-content/plugins/wpmarketplace/readme.txt

这在我的服务器上不存在(大多数GET资源不存在,并且有大量的txt和css文件正在被GET)。 也有各种PHP文件POST请求,导致相同的缓慢,并最终冻结。

所以我的预感是,这是一个很差的脚本来检查易受攻击的网站,导致一个DoS。 或者它可能实际上是一个DoS,而不是一个多function的脚本,但是从我看过一个这样的年代开始,现在人们在做DDoS。

我目前正在研究一些脚本来控制它。 一旦我有他们,我会回来,也许会帮助别人。

编辑:

经过多次testing,我想我终于设法控制了事情。 假设你制作一个新的脚本/root/check_httpd.sh(底部的解释)

 cnt=`ps -Af | grep httpd | grep -v rotatelogs | grep -v grep | wc -l` now=`date +%Y-%m-%d_%H-%M` # change the 40 below to something meaningful to your server if [ $cnt -ge 40 ] then /usr/bin/wget -q -O /root/apache_status_$now http://<your server here>/server-status /sbin/service httpd restart fi # change hda to your partition/disk which is being "killed" by httpd during the freeze dsk=`/usr/bin/iostat -dx /dev/hda 5 2 | grep hda | tail -1 | awk '{print $12}'` if (( $(echo "$dsk > 98" |bc -l) )) then /bin/sleep 5 dsk=`/usr/bin/iostat -dx /dev/hda 5 2 | grep hda | tail -1 | awk '{print $12}'` if (( $(echo "$dsk > 98" |bc -l) )) then /sbin/service httpd restart fi fi 

然后你添加这个cron就像:

 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58 * * * * /root/check_httpd.sh 

别忘了

 chmod +x /root/check_httpd.sh 

和解释。

所以在我的情况下,最初,我注意到(在冻结期间)httpd状态页面会显示大量的“W”状态的httpd子,在各种资源上有不同的等待时间,有些有效,有些是无效的。 我花了很多时间用不同的选项来获得基于状态页面的90%以上的情况,以查找服务器何时被冻结而不是大量使用。 没有运气。 但后来我通常认为,即使在“繁重”的负载下,我的httpdsubprocess数仍然会低于20-30(我的网站是“lite”),所以我做了一些testing,发现有40个httpd子计数总是在冻结过程中发生(注意:您可以从该部分中删除wget的状态,在那里您可以确认在重新启动期间您select的任何数值都确实冻结。

但是,这一点不会削减。 在服务器冻结超过24小时之前,我还是遇到了这样的情况:有40个计数器会启动。search更多的时候,我发现在我运行的实用程序上运行了一个腻子terminal,所以无论服务器什么时候冻结,我都可以看到确切的资源消耗那么多。 我注意到这是硬盘。 所以第二次检查硬盘的使用情况,但是正如你所知道的那样,hdd的使用会不时出现,所以1次检查会导致误报。 我所做的是在几秒钟后再次进行检查,然后根据需要重新启动httpd。

您需要在您的服务器上稍微玩一下,并调整阈值以使其适合您的环境和使用模式。