采用 prefork 模型的 Apache 每个进程使用 1000 MB 内存

采用 prefork 模型的 Apache 每个进程使用 1000 MB 内存

我目前正在开发一个使用 Apache 运行 prefork 内存模型的网站。以下是 httpd.conf 中的配置

<IfModule prefork.c> 
  StartServers            30
  MinSpareServers         15
  MaxSpareServers         30
  MaxClients              96 
  ServerLimit             512
  MaxRequestsPerChild     0
</IfModule>

以下是顶部的示例行

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND           
29261 apache    15   0 1003m 231m  53m S 16.3  2.9   1:47.68 httpd              

以下是加载的apache模块

core prefork http_core mod_so mod_auth_basic mod_authn_file 
mod_authz_host mod_authz_user mod_include mod_log_config 
mod_logio mod_env mod_ext_filter mod_mime_magic mod_expires 
mod_deflate mod_headers mod_usertrack mod_setenvif mod_mime 
mod_status mod_autoindex mod_info mod_vhost_alias mod_negotiation 
mod_dir mod_actions mod_alias mod_rewrite mod_cgi mod_version 
mod_realip2 mod_php5 mod_ssl

我不确定这些模块是否都被使用了。

以下是加载的php扩展

date, libxml, openssl, pcre, zlib, bz2, calendar, ctype, 
curl, hash, filter, ftp, gettext, gmp, session, iconv, 
posix, Reflection, standard, shmop, SimpleXML, SPL, sockets, 
exif, sysvmsg, sysvsem, sysvshm, tokenizer, wddx, xml, 
apache2handler, memcache, uploadprogress, dbase, dom, 
eAccelerator, gd, json, mbstring, mcrypt, memcached, mongo, 
mysql, mysqli, newrelic, PDO, pdo_mysql, pdo_sqlite, xmlreader, 
xmlwriter, xsl, zip

为什么 apache 会在每个进程中使用如此多的内存?是因为这些模块吗?如果是这样,那么其中是否存在占用大量内存的情况,我可以开始查看它们是否正在使用?或者可能是因为 php 扩展?其中是否存在占用大量内存的情况?

php 内存限制设置为 256MB。

每个加速器配置512MB内存。

服务器无法处理甚至略高于平均水平的负载,因为一旦流量增加,交换使用就会开始,导致系统无响应。该服务器总共有 8GB 的​​ RAM,它是一个专用的四核服务器。

在此先感谢任何帮助解决该问题的人。

答案1

首先,关于确定内存使用情况。VSS/VSIZE/VIRT 不是进程对 RAM 的实际使用情况(@psusi 也指出了这一点)。有一些工具可以计算实际使用情况,其中一个是 Yahoo! 的 Peter Willis 提供的非常有用的工具:

http://psydev.syw4e.info/new/misc/meminfo.pl

关于您的配置有两个重要说明。通常不建议使用:

MaxRequestsPerChild     0

除非您自己编写了应用程序。内存泄漏很常见,因此在数百(或数千)个请求之后,子进程的内存使用量将会增加并最终超过合理水平。您可能应该将其设置为 ~200,然后查看在 200 个请求之后它们使用了多少内存。这必须与服务器生成所需的时间进行权衡。如果分叉新子进程需要几秒钟和大量资源,您需要增加该值(如果是轻量级的,甚至可以减少该值)。

其次,除非您专门使用线程不安全的模块,否则 prefork 并不是真正的首选,因为它使用更多内存:

http://httpd.apache.org/docs/2.0/misc/perf-tuning.html#compiletime

prefork MPM 使用多个子进程,每个子进程都有一个线程。每个进程一次处理一个连接。在许多系统上,prefork 的速度与 worker 相当,但它占用更多内存。

最后,您可能希望仔细检查并删除不需要的模块。据我所知,没有自定义模块可以帮助完成此操作,您通常会尝试删除尽可能多的模块并验证系统是否仍然有效。这基本上是猜测和检查,但值得花一两个小时来做​​。

答案2

ps 说每个进程都是这样也是有原因的。并不是每个进程都使用了那么多内存。请参阅下面的内容,了解有关 ps 和内存的更多信息

http://virtualthreads.blogspot.com/2006/02/understanding-memory-usage-on-linux.html

相关内容