![无论访问量对服务器造成的实际压力如何,较高的 MaxClient 值是否都会导致 CPU 负载问题?](https://linux22.com/image/578919/%E6%97%A0%E8%AE%BA%E8%AE%BF%E9%97%AE%E9%87%8F%E5%AF%B9%E6%9C%8D%E5%8A%A1%E5%99%A8%E9%80%A0%E6%88%90%E7%9A%84%E5%AE%9E%E9%99%85%E5%8E%8B%E5%8A%9B%E5%A6%82%E4%BD%95%EF%BC%8C%E8%BE%83%E9%AB%98%E7%9A%84%20MaxClient%20%E5%80%BC%E6%98%AF%E5%90%A6%E9%83%BD%E4%BC%9A%E5%AF%BC%E8%87%B4%20CPU%20%E8%B4%9F%E8%BD%BD%E9%97%AE%E9%A2%98%EF%BC%9F.png)
我以为 MaxClients 只是一个限制,当服务器达到限制时,它会向某些人显示空白页,以防止过载。我还以为这只是一个限制,所以除非需要,否则不会使用备用连接,之后它们会被释放。但我的服务器机器似乎否认这一切。
几个月前,我的服务器机器的 Apache 日志中反复出现“考虑提高 MaxClient”行。在我意识到发生了什么之前,服务器堆积了 CPU 负载,然后机器彻底崩溃了。在我将 MaxClient 值从 500 提高到 900(MPM 预分叉)之前,这种情况在大约一周内发生了 3 次。
[最后一次坠毁*]很久以后,两周前,由于实际访问量而出现了一次连接高峰(我们发布了一些“独家”信息)。它可能达到了 900 的限制(它在日志中出现过一次),服务器开始滞后,几分钟后又崩溃了。最后断网了 2 小时(文件系统已损坏)。
所以现在我的 MaxClient = 2000,但我遇到的问题出现在 [上次崩溃*] 前几天。所以我实际上不知道这是否相关。
这些是我的症状:
- 随机增加 CPU 负载(最高可达 12,通常负载低于 5),直到重新启动 Apache,重新启动后负载迅速下降
- 重启后需要几个小时甚至几天才能再次出现
- 这种负载增加似乎在现有负载上增加了“5”,这意味着,早上它大约是 2+5,如果我不重新启动 Apache,实际访问量会更高(峰值为 12-14)
- 当达到峰值时,它不会下降,它会一直停留在那里直到重新启动,无论是白天还是实际访问量
- 似乎负载问题都是随机发生的,高峰期、晚上、早上、周一、周六都无所谓
- 这种负载似乎根本不影响性能(但我不喜欢它,如果不出意外,它会缩短 CPU 寿命)
- 负载肯定是由 Apache 引起的(top、htop 检查)
这是我的 MPM prefork 设置(24GB RAM,Apache + MySQL + 数据):
StartServers 5
MinSpareServers 5
MaxSpareServers 10
ServerLimit 2000
MaxClients 2000
MaxRequestsPerChild 0
另外,我已关闭 KeepAlive。这会对此行为产生一些影响吗?
KeepAlive Off
MaxKeepAliveRequests 0
KeepAliveTimeout 2
从服务器状态:当前正在处理 40 个请求,现在有 0(或最多 12)个空闲工人。不过现在是星期六晚上。现在我得到的数字非常相似,但现在是阳光明媚的星期天中午……该死的 xD
一开始我以为是 php 脚本有问题,但现在我不确定了。问题第一次出现时似乎没有人更改任何脚本。达到限制时奇怪的崩溃行为告诉我,可能存在其他问题(尤其是当上升值有帮助时,看起来不像是内存不足)。
抱歉,描述得这么累。我通常不会在搜索之前询问,但今天我真的没什么主意了。我不能一直重启。这 2 秒没关系,但也有可能一些主要脚本无法正确完成工作,或者编辑器在错误的时刻按下保存按钮时丢失了他的工作。
因此,为了简单起见,如果这可能与我的负载问题有关,我也希望您对我的 Apache 设置提出意见。
答案1
即使有 24 GB 的 RAM,您的 MaxClients 也可能太高了。这是我用来近似平均 httpd(如果在 Debian 发行版中,则用 apache2 替代)进程大小的方法:
ps -ylC httpd --sort:rss | awk '{sum+=$8; ++n} END {print "Tot="sum"("n")";print "Avg="sum"/"n"="sum/n/1024"MB"}'
得到该数字后,取系统 RAM 的 90%(假设该服务器仅提供 Web 流量服务,没有 MySQL 和其他服务)并除以平均 httpd 进程大小,例如:
22,118 MB / 50 = 442
因此,您需要将 MaxClients (和 ServerLimit) 设置为 440 左右。
由于您在这台服务器上也有 MySQL,因此您需要更保守一些,也许取系统 RAM 的 50% 并将其除以平均 httpd 进程大小,得出 MaxClients 为 245。
答案2
尝试这个:
Timeout 300
KeepAlive On
MaxKeepAliveRequests 28800
KeepAliveTimeout 260
ListenBackLog default
StartServers 4
ServerLimit 16
ThreadLimit 2048
MaxClients 2048
MinSpareThreads 32
MaxSpareThreads 64
ThreadsPerChild 128
MaxRequestsPerChild 0
答案3
作为一种解决方法,您可以尝试将 MaxRequestsPerChild 设置为非零值。