我们看到 Apache 进程在看到 POST 请求后挂起,想知道解决此问题的最佳途径是什么。当我查看挂起请求的扩展服务器状态时,我看到以下条目:
53-31 28616 9/13/74232 W 0.71 7174 0 7.6 0.01 961.47 xxx.xxx.xxx.xxx www.mysite.com POST xxxxx HTTP/1.1
27-31 7629 1/34/107074 W 0.96 4480 0 0.0 0.39 1394.10 xxx.xxx.xxx.xxx www.mysite.com POST xxxxx HTTP/1.1
进程本身总是在做一些事情,通常会消耗大量的 CPU 资源,直到我们将其终止。
最初我以为是一些错误的代码——所有东西都在运行 PHP 脚本——但过了一会儿,我们看到由各种不同的请求导致的挂起进程,其中许多请求很简单,但始终显示 POST 是最后处理的请求类型。
我不指望社区能够在没有看到实际代码运行的情况下立即解决这个问题;我真正寻找的是调试这个问题的最佳途径,因为我没有主意了。我想到了一些事情:
是否有类似于 jstack 的工具可以让我们转储和检查挂起进程的堆栈跟踪,从而提供有用的信息?
有没有办法跟踪有用的输入,以帮助解决此问题?我尝试将 Apache 日志设置为调试并让其输出 POST 查询参数,但记录的数据量太大,我很难知道要查找什么。这里有最佳实践吗?
服务器使用 prefork,MaxClients 设置为 150,KeepAlive 设置为 5。在正常负载情况下,通常有 30-50 个进程正在运行;在高负载情况下,进程数量接近 100。我们已经看到在任何负载情况下都会发生挂起进程行为。配置中是否有我可能特别关注的部分?
该服务器是 EC2 上 Debian Lenny 下运行的 Apache 2。
非常感谢!
答案1
一个非常有用的实用程序是阿帕奇。它类似于 top,但会实时监控您的 Apache 访问日志。您可以根据多种不同的标准对结果进行排序——请求量、传输的千字节数等等。
不知道您的情况如何,但我发现 Apachetop 中有一些损坏的重写规则。例如,在一个案例中,重写规则指向一个本地的但不存在的页面,并通过执行重定向来实现这一点(R在 RewriteRule 行中)。不幸的是,Apache 的错误文档也配置错误 ——ErrorDocument 404 http://thesiteimtalkingabout.com/404.html
并且 404 页面也丢失了。
这种组合导致了死亡螺旋式的体验:一个看似无辜的页面导致 Apache 递归调用自身,并且 Apache 变得完全没有响应。
那个战争故事可能对你没有任何帮助,所以我向你指出了其他几种调试技巧:
使用
strace
。从服务器状态中查看行为不当的 Apache 进程的 pid,然后执行类似操作,strace -fF -s 128 -p thatbastardpid -o /tmp/wtf
通过读取/tmp/wtf文件。或者,要查看统计数据,strace -fF -p thatbastardpid -c -o /tmp/wtf
tcpdump
使用或捕获网络流量wireshark
并查看 PHP 进程是否发生异常。
希望这能有所帮助。祝你好运!
答案2
创建一个简单的 php 页面,该页面只接受一个帖子变量并将其打印在屏幕上。阻止所有客户端,以便只有您可以访问服务器。重新启动 Web 服务器。现在使用您的简单脚本并仅发送一个帖子变量。
如果 apache 仍然挂起,则问题出在 POST 方法上。如果此方法有效,则大量脚本的问题可能是由于所有脚本中都包含公共文件所致。