我正在运行一台 CentOS 6.7 机器(16 GB vRAM、8 vCPU),上面有一个简单的 Web 服务器设置(Apache/2.2.15、PHP/5.3.3、MySQL/5.1.66),托管一个在线商店,页面浏览量适中(每天约 2,000 至 4,000 次)。
在过去 3 年中,服务器运行平稳,无需更改配置。现在,从上周开始 - 不知何故一夜之间 - Apache/HTTP 在短时间(约 30 分钟)后反复变得无法访问。我检查了一些参数,发现有很多 httpd 进程正在运行。ps axf | grep httpd | wc
显示如下内容:
387 2344 18354
而负载并不是很令人兴奋。top
看起来像这样:
极少数 httpd 进程会不时再次释放,但总数几乎一直在不断增加。如果我运行service httpd reload
,进程数会降回 0,并在接下来的几分钟到几小时内再次开始增加。过了一会儿,Apache 的日志告诉我:
[error] server reached MaxClients setting, consider raising the MaxClients setting
我这样做了,还调整了其他不同的配置参数,但没用。无论设置的值是什么MaxClients
,ServerLimit
Apache 都不会停止生成新的 httpd 进程,直到达到这些限制。此后,该网站将无法再访问。
根据 AWStats 的数据,页面点击量没有增加。此外,PHP 应用程序没有任何变化。除了 30 分钟后所有请求被阻止的故障外,网站运行速度一如既往地快。作为一种肮脏的临时解决方法,Cron 每半小时重新加载一次 Apache。
过去 3 年中 Prefork/Worker 的设置如下:
<IfModule prefork.c>
StartServers 4
MinSpareServers 5
MaxSpareServers 10
ServerLimit 128
MaxClients 128
MaxRequestsPerChild 600
</IfModule>
<IfModule worker.c>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
我提出以下观点:
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 10
ServerLimit 640
MaxClients 640
MaxRequestsPerChild 1000
</IfModule>
<IfModule worker.c>
StartServers 4
MaxClients 300
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
进行此更改后,Apache/HTTP 在大约 1 小时后变得不可用。
这种情况怎么会突然发生?我该怎么做才能进一步调查这种奇怪行为的根源?