阿帕奇死了 怀疑是ulimit,但不能重现

阿帕奇昨晚去世了。 错误日志显示这一点

[alert] (11)Resource temporarily unavailable: setuid: unable to change to uid: 48

浏览互联网,每个人似乎都认为这是在Linux的ulimit问题。 如果我理解正确,ulimit有一个默认的限制到任何非root用户并发进程的数量为1024.如果达到用户(在这种情况下,apache)的最大数量,它不能创build更多的进程。 这就解释了为什么当它试图产生一个新的孩子时,它不能设置给apache用户。

昨天晚上,我们有一个networking应用程序的用户在大约1分钟的时间内向同一页面发出了1100多个GET请求,这就是服务器死亡的时间。

我的Apacheconfiguration文件有这样的:

 <IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 2000 MaxClients 2000 MaxRequestsPerChild 4000 </IfModule> KeepAlive On MaxKeepAliveTimeout 5 KeepAliveTimeout 5 

如果我的MaxClients是2000,MaxSpareServers是20,那么这意味着为了让Apache达到进程的限制,它将不得不有1000多个繁忙进程,我根本没有看到发生这种情况,考虑到这些GET请求很小,很容易处理20-30个请求。 最重要的是,MaxRequestsPerChild被设置为4000,所以它不应该产生这么多新的孩子,对吧? 那么,为什么它不能setuid,这真的是罪魁祸首吗?

我已经使用了Apache的ab工具来尝试在一个不太强大的本地构build中重现这一点,我不能。 即使是function不太强大的硬件,也可以在一分钟内处理好几千个连接,性能也不错 如果我尝试通过networking同时访问服务器,它会变得糟糕,但Apache不会陷入困境。

所以这是我的问题:

  1. 有没有更好的方式来configurationprefork模块? 我们只是从旧的服务器迁移到这个较新的服务器。 老一点的ServerLimit和MaxClients设置为512.我想也可以设置2000,以避免在可预见的将来再次改变它。
  2. 我已经尝试调整ulimit nproc到一个低数字来尝试和重现错误。 在limits.conf中,我设置了* hard nproc 15 ,但是当我运行ab时,Apache仍然会产生大约30个孩子。 我错过了什么吗?
  3. 尽pipe第二,是在这里提高nproc设置为更高的东西像10000?
  4. 我也想实施一些防止用户做这么多尝试的东西。 在过去,我使用iptables来阻止一分钟内发出5个以上SSH请求的用户。 我想为http请求做类似的事情,但我想知道是否有更好的解决scheme。 我听说过fail2ban和mod_security等,但我不知道他们做了什么。 在这种情况下他们会受益吗? 还有其他build议吗?

服务器信息:RHEL 6.3,Apache 2.2.15