Apache 内存不足

Apache 内存不足

我在一台 512MB 内存的 VPS 上使用 CentOS 5。我发现 httpd 经常耗尽内存,导致整个系统运行缓慢。但我找不到原因。

当我用top它来监控进程时,有时其中一个进程httpd会占用 90% 以上的内存,然后 SSH 会挂起几秒钟。当top再次刷新时,它httpd已被内核杀死。几分钟后,这个问题又会重复出现。

这是系统日志:http://pastebin.com/bszy9ahq

我的 Apache prefork 配置:

<IfModule prefork.c>
StartServers 1
MinSpareServers 3
MaxSpareServers 7
ServerLimit      128
MaxClients       128
MaxRequestsPerChild 4000
</IfModule>

这是httpd -V

Server version: Apache/2.2.3
Server built:   Mar 24 2012 13:32:42
Server's Module Magic Number: 20051115:3
Server loaded:  APR 1.2.7, APR-Util 1.2.7
Compiled using: APR 1.2.7, APR-Util 1.2.7
Architecture:   32-bit
Server MPM:     Prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/prefork"
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=128
 -D HTTPD_ROOT="/etc/httpd"
 -D SUEXEC_BIN="/usr/sbin/suexec"
 -D DEFAULT_PIDLOG="run/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_LOCKFILE="logs/accept.lock"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"

有什么方法可以知道哪个脚本导致了内存问题,或者只是与 Apache 有关?以及如何解决...

答案1

系统内存不足,并决定终止 apache 以腾出空间。占用所有内存的不一定是 apache。512Mb 对于 128 个 httpd 进程来说可能比较紧张 - 但这个数字可能会有很大差异。您是否查看过 httpd 实例使用了多少内存?不要费心尝试从静态快照中计算出来 - 将内存使用情况(减去缓冲区和缓存)与 httpd 实例数作图,然后进行最小二乘回归 - 斜率是每个实例使用的内存量。然后找出关闭 Apache 时系统使用了多少内存。根据从磁盘读取的内容量,您应该争取至少有 ~20% 的内存可用于缓存/缓冲区。

您是否调整了 httpd.conf?删除了所有冗余模块?应启用 Keepalive,但超时时间最多为 2 秒。启用静态内容的输出压缩和缓存。

如果您怀疑 Apache 存在内存泄漏,请尝试减少 MaxRequestsPerChild。

有时其中一个 httpd 会占用 90% 以上的内存

这更表明存在失控脚本/模块。

有什么方法可以知道什么脚本

从您提供的信息来看,没有找到任何信息 - 没有任何东西告诉我们您使用的是什么脚本语言,也没有告诉我们如何从 httpd 调用它。如果是 PHP,请尝试添加一个 autoprepend 脚本,例如...

<?php

register_shutdown_function('logmem');

function logmem()
{
    apache_note('x-php-peak-mem', memory_get_peak_usage());
}

并在您的访问日志中报告该值:

"%{x-php-peak-mem}n"

显然,这只会报告成功完成的请求 - 但这是一个开始。

同样,如果是 PHP,那么将内存限制设置得太高(尽管这也适用于其他 OO 语言)可能会因抑制垃圾收集而适得其反。

(顺便说一句,如果几分钟后内存不足,那么“StartServers 1”就太愚蠢了)

答案2

要解决此问题:

  • 你的配置还一样吗?
  • 访客数量还一样吗?
  • 有任何脚本或者模块被改变吗?

如果您的网站相当繁忙,那么 512 MB 对 Apache 来说不算多。您可能需要调整一下您的配置。

相关内容