我目前正在运行一个 Web 应用程序,每天有几个 (~15) 用户登录一次,然后让 Web 应用程序保持打开状态,每 5 分钟自动刷新一次新内容。每个用户打开的时间通常约为 15-18 小时。
然而,当用户达到临界点(约 30-40)时,一切都开始急剧变慢,HTTPD 进程的内存使用量开始激增。我添加了一个 cron 作业,每小时重新启动一次 apache,但这只能起到一点作用。所有内容都是动态生成的,每次刷新一次,因此缓存页面不是一个选择。
我已经开始尝试 Timeout、MaxRequest 和 KeepAlive 选项,但是如果能得到任何指导我将非常感激,因为过去我一直将这些选项保留为默认值。
这是我所拥有的。任何 Apache 天才都有关于如何针对上述情况优化此配置的想法吗?我认为较长的超时时间是好的,因为加载时间有时会变得非常长。
# Timeout: The number of seconds before receives and sends time out.
Timeout 200
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
KeepAlive On
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
MaxKeepAliveRequests 100
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
KeepAliveTimeout 60
# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# ServerLimit: maximum value for MaxClients for the lifetime of the server
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule prefork.c>
StartServers 16
MinSpareServers 10
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
</IfModule>
答案1
(为了清楚起见,我简化了数字,尤其是内存部分太高了)
您的 MaxRequestsPerChild 目前为 4000,假设您每天有 50 名用户,每个人每 5 分钟刷新一次,持续 18 小时,则每小时有 600 个请求,每天有 10800 个请求。作为参考,一个用户每天使用 218 个连接。
这意味着子进程每天重新启动 2.7 次。如果您的应用程序每次重新加载使用 50M 内存,并设法释放其中的 49M(每次刷新 1M),50 个用户使用 50M,4000 次重新加载使用 4G。那么子进程将被终止。
您应该检查您的应用程序使用了多少内存,并根据这些内存设置这些值。
如果您的服务器有 20G 内存,那么 1M 的泄漏会起到一定的作用,但将 MaxRequestsPerChild 更改为例如 1000 会使子进程重启前的内存消耗减少四倍。
需要注意的是,您可能希望将 MaxClients 减少到 100 左右,并确保实际上没有比您想象的更多的用户。这样,意外问题就不会因请求过多而导致服务器 OOMing。由于用户每 5 分钟才刷新一次,因此 KeepAliveTimeout 可能为 15 秒左右。
答案2
我认为你需要玩每个子进程的最大请求数指令。每小时重启 Apache 对我来说听起来不是一个优雅的解决方案。MaxRequestsPerChild 每个进程在处理设定的请求数后将自动重启。尝试将其设置为 100 ?
还可以使用更轻量的 Web 服务器(例如nginx) 为缓慢的客户端提供静态媒体服务将会减轻 Apache 的负载。