Apache MaxClients到达,服务器无响应,甚至非高峰

我们有一台几乎每天都没有响应的Apache服务器。 通过检查/ server-status(mod_status)我们可以看到我们有60个subprocess都处于“W”(发送应答)状态。

  1. 如果我们运行service httpd restart一切恢复正常,问题消失了一天左右。
  2. 如果我们不是重新启动Apache来终止每个subprocess,问题仍然存在(这是我们访问服务器状态的唯一方法,直到所有进程都进入“W”状态)。
  3. 对我来说,似乎我们的PHP脚本永远不会完成,当问题发生时,这使我认为这是一个MySQL,Solr,或PHP / Apache的超时问题。
  4. 然而…
    • Solr / MySQL立即响应。
    • 有大量的MySQL连接可用(我们使用AWS-RDS,允许的最大连接数大于Apache进程数)。
    • RAM仍然很好(每个进程是10米x 60 = 600Mb的RAM,直到有足够的空闲)。
    • PHP的max_exectution_time设置为“30”。
    • Apache TimeOut被设置为“60”。
    • 我们不使用持续的MySQL连接。
    • 我们使用curl_setopt($conn, CURLOPT_FORBID_REUSE, 0)来查询Solr(我希望这会通过curl正确地收集垃圾,如果连接消失的话)。
  5. 看来尽pipe许多进程永远不会结束……我离开了一个进程,同时杀死了所有其他进程,这个进程仍然活着2个小时,仍然服务于同一页面(我可以看到这/服务器状态)通常需要50ms来响应。
  6. 我们不使用set_time_limit(0)或者在我们的代码中使用任何愚蠢的东西。
  7. 我假设省略set_time_limit意味着脚本将在max_execution_time之后完成。

我有一个理论认为,Apache的ListenBacklog设置得太高,每当我们杀死进程时,60个新进程立即启动,所有这些都试图对已经离开的客户做出响应。 这将解释为什么当我们重新启动服务器时问题消失了。 但似乎ListenBacklog没有设置,因此默认的“511”将被使用。 我试图连续几次杀死所有的subprocess,以清除积压,但问题仍然存在…所有PHP页面的新请求都会永远响应(大多数不响应)。

PHPconfiguration:

 max_execution_time = 30 max_input_time = 60 safe_mode = off 

Apacheconfiguration:

 KeepAlive off <IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients 60 MaxRequestsPerChild 1000 </IfModule> 

我用完了想法…任何提示将不胜感激!

我build议的故障排除步骤是:

  • strace -p $PID挂起的进程,看看系统调用,如果有的话,它卡住了
  • 在这个过程中使用lsof -p $PID来查看打开的文件句柄或套接字是否可以提供线索
  • tcpdump -vv -A -s1500 port 80 ,查看stream量是什么以及响应出错的地方。