我经常收到以下消息:
我猜这是因为我的 RAM 不够。对吗?
我能做些什么吗?
谢谢
更新:我已经安装了 MPM prefork
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
答案1
这是你的问题:
MaxRequestsPerChild 0
零值意味着各个子进程永远不会退出,从而慢慢消耗越来越多的 RAM(这取决于代码需要多长时间)。将该值设置为合理的某个值(尝试从 5000 开始),然后经过一段时间,Apache 启动以处理负载,您将在“ps”中看到 Apache 子进程在常驻(RSS)内存中达到峰值的位置。
使用此值作为最大子进程大小,然后必须将 MaxClients 设置为要使用的内存。因此,如果您有 256MB,则需要为操作系统留出一些内存,因此假设 Apache 的内存为 248MB(这并不准确,取决于系统上的其他内容)。这意味着每个 Apache 子进程最多只能有 1.5MB,这有点荒谬 - 大多数 Apache 进程的平均运行内存范围往往在 15MB 左右(有些更高)。
假设您有一个平均大小为 20MB 的 Apache 子进程,有 5000 个请求 - 如果您将请求数减少到 4000,则可以将其减少到 15MB(示例);这是您必须考虑的事情。无论您想出什么组合,请进行计算并将 MaxClients 设置为最大值(例如,248/15 = 16)。
您必须稍微调整一下这些值,缩小每个值的范围,以便获得正确的内存设置。如果当前设置为 0,Apache 就会失控。
答案2
您能做的最重要的事情就是精简所有守护进程,使其仅使用完成工作所需的内存。减少数据库内存缓存、减少 httpd 子进程的数量、禁用未使用的 httpd 模块等。显然,这会影响性能,因此您必须在之后监控系统一段时间并根据需要进行调整。
抵制通过增加交换空间来修补问题的诱惑。这实际上不是一个解决方案,因为系统性能会下降。
答案3
我猜这是因为我的 RAM 不够。对吗?
系统终止 Apache 进程,因为它需要更多内存
我能做些什么吗?
添加内存、交换或调整 mpm 设置(/etc/apache2/apache2.conf,搜索 MPM 特定)
答案4
您的 apache 中可能运行着一个有缺陷的应用程序,例如编写不当的 php 扩展或自定义 apache 模块或只是一个失控脚本。您的 maxrequestsperchild 设置为零,因此 apache 的 fork() 子进程将“永远”保持活动状态以处理请求(其中永远是相对于您的 apache 主进程的范围定义的)。在执行此操作时,您的有缺陷的应用程序会请求内存而不会释放它,因此子进程将继续消耗内存。操作系统将这些进程标记为下一次内存不足的良好候选者。如果您想隐藏错误并假装什么都没发生,请将 maxrequestsperchild 设置为 500 之类的值(此值实际上取决于您的服务每秒处理的请求数,例如,如果您提供 500reqps,那么 5000 将是一个很好的起点,这样您就不会导致 fork thundering herds)。不要使用 mpm worker,当操作系统决定强制释放一些内存时,它将完全杀死整个线程池,而且大多数 php 扩展并不完全是线程安全的(假设您正在使用 php)。最好的办法是开始调试。如果不使用 gdb,那么我相信您可以找到一些为调试和分析正在运行的应用程序而编写的 apache 模块。