在具有 8GB RAM 的四核服务器上,我的 apache 进程最多使用 2.3GB RES 内存和 2.6GB VIRT 内存。以下是一份副本top -c command
:
有没有办法减少这些 apache 进程的内存使用量?
这些是我的httpd.conf
设置:
Timeout 160
TraceEnable Off
ServerSignature Off
ServerTokens ProductOnly
FileETag None
StartServers 6
<IfModule prefork.c>
MinSpareServers 4
MaxSpareServers 16
</IfModule>
ServerLimit 400
MaxClients 320
MaxRequestsPerChild 10000
KeepAlive On
KeepAliveTimeout 4
MaxKeepAliveRequests 80
笔记:似乎存在一些连接延迟。此外,如果 16 个连接使用 8GB 或内存。我有点担心,如果我的服务器有 300 个连接,它就会离线。此外,在 Munin 中,我可以看到已提交的内存在 2 周内从几 GB 上升到 80GB。每次 apache 重新启动时,它都会再次下降到几 GB
答案1
Apache 中的内存由模块使用,由模块使用的内存使用。禁用未使用的模块,并查看剩余需要调整的模块,使用pmap <PID>
以查看内存分配方式。使用dmalloc
和valgrind
调试剩余的内存分配问题。
答案2
这是异常高的内存使用率。可能存在内存泄漏。
现在,尝试更新您的 Apache2 安装(包括模块)并减少 的数量MaxRequestsPerChild
,即减少到 500。后一个设置从“处理的请求”角度实质上减少了 Apache2 子进程的最大生命周期。也就是说,如果存在内存泄漏,它们将不会急剧增加。
答案3
删除不必要的模块是解决问题的基本方法,但您必须运行大量模块才能获得占用 2GB RAM 的 Apache 进程。更可能的是,您拥有的动态代码模块(例如mod_php
)正在运行令人讨厌的、有漏洞的代码,或者代码编写不当并本身就泄漏内存的模块。
你可以把MaxRequestsPerChild
内存降到很小,也可以正确地完成任务并找到内存泄漏。折衷方案是至少将动态代码执行推到单独的进程(使用 suPHP、suexec、php-fpm 等),无论如何,出于安全考虑,这都是一个好主意。
答案4
我不知道您看到的是哪种流量需要这样的设置,但似乎可以降低您的设置以更好地利用资源,因为似乎您从一开始就过度使用 Apache,并且没有针对实际站点流量进行配置。除非您可以提供一些站点统计数据来证明初始配置的高数字是合理的。
关键是MaxRequestsPerChild
,这将有助于通过更频繁地重新生成父进程来防止内存泄漏。另外,我降低了ServerLimit
和,MaxClients
因为这与每秒连接的客户端数量有关。因此,如果有人从您的网站抓取一个页面,并且它在 1 秒内呈现,猜猜会发生什么?服务器已经完成了它的工作。与此相关,我降低了MaxKeepAliveRequests
和,KeepAliveTimeout
以便再次更加现实。我还降低了一般时间,Timeout
因为 120 秒是 2 分钟。如果客户端需要 2 分钟才能从您那里获取内容,那么在服务器超时之前给他们的时间已经足够多了。我喜欢保持这个数字,以防出现高流量情况。
请记住:Web 服务器不会在服务器和客户端之间保持持续的连接。客户端发出请求,服务器提供页面,仅此而已。因此,请记住这一点。此外,请阅读另一个答案我向另一位担心其网络服务器内存使用情况的发帖者提供了此信息。
Timeout 120
TraceEnable Off
ServerSignature Off
ServerTokens ProductOnly
FileETag None
StartServers 6
<IfModule prefork.c>
MinSpareServers 4
MaxSpareServers 16
</IfModule>
ServerLimit 80
MaxClients 60
MaxRequestsPerChild 2000
KeepAlive On
KeepAliveTimeout 2
MaxKeepAliveRequests 30