Apache HTTPD使用内存直到挂起


apache httpd using up mem until hang

看来我们可能有一个(不断增长的)内存问题在我们的apache httpd某处。

快速图片:http://screencast.com/t/NGAzarD87O

注意,它在原始(物理)服务器上运行了一段时间。现在在新的VM上(有更多的内存和cpu),它运行,但慢慢地消耗内存/交换空间,直到系统挂起。

如果我重新启动httpd, mem跳起来(如果我们抓住它)。

httpd.x86_64                           2.2.3-76.el5_9         installed
PHP 5.1.6 (cli) (built: Jun 22 2012 06:20:25)
MySQL Server version: 5.0.95

我不认为它可以是运行/etc的任何脚本,因为它们在物理机器上运行了很多年。我们尝试在新机器上匹配所有配置(http, php等),但无法弄清楚为什么httpd一直在增长。

$ ps -ylC httpd --sort:rss
S   UID   PID  PPID  C PRI  NI   RSS    SZ WCHAN  TTY          TIME CMD
S     0 13814     1  0  78   0 29208 68382 -      ?        00:00:00 httpd
S    48 20854 13814  0  76   0 34876 70930 semtim ?        00:00:00 httpd
S    48 20853 13814  0  75   0 36592 71387 semtim ?        00:00:00 httpd
S    48 13822 13814  0  75   0 36780 71430 semtim ?        00:00:00 httpd
S    48 20696 13814  0  75   0 37092 71520 semtim ?        00:00:00 httpd
S    48 13821 13814  0  75   0 37184 71529 semtim ?        00:00:01 httpd
S    48 13820 13814  0  75   0 37220 71527 -      ?        00:00:01 httpd
S    48 13824 13814  0  75   0 37236 71513 semtim ?        00:00:01 httpd
S    48 13818 13814  0  75   0 37636 71547 semtim ?        00:00:01 httpd
S    48 13819 13814  0  75   0 37636 71617 semtim ?        00:00:01 httpd
S    48 13823 13814  0  75   0 37888 71689 semtim ?        00:00:01 httpd
S    48 13825 13814  0  75   0 37900 71676 semtim ?        00:00:01 httpd

更新:在写这个问题的时候(可能10-15分钟),我重新运行了上面的RSS,所有RSS都位于~51072,而不是上面的~37000

下面是python程序

的运行
 Private  +   Shared  =  RAM used       Program
.... SNIPPED OUT ....
208.0 MiB +  25.5 MiB = 233.5 MiB       httpd (12)
---------------------------------
                        477.1 MiB

PHP内存设置:

max_execution_time = 30 
max_input_time = 60  
memory_limit = 152M  

模块:

$ apachectl -M
httpd: Could not reliably determine the server's fully qualified domain name, using 192.168.1.2 for ServerName
Loaded Modules:
 core_module (static)
 mpm_prefork_module (static)
 http_module (static)
 so_module (static)
 auth_basic_module (shared)
 auth_digest_module (shared)
 authn_file_module (shared)
 authn_alias_module (shared)
 authn_anon_module (shared)
 authn_dbm_module (shared)
 authn_default_module (shared)
 authz_host_module (shared)
 authz_user_module (shared)
 authz_owner_module (shared)
 authz_groupfile_module (shared)
 authz_dbm_module (shared)
 authz_default_module (shared)
 ldap_module (shared)
 authnz_ldap_module (shared)
 include_module (shared)
 log_config_module (shared)
 logio_module (shared)
 env_module (shared)
 ext_filter_module (shared)
 mime_magic_module (shared)
 expires_module (shared)
 deflate_module (shared)
 headers_module (shared)
 usertrack_module (shared)
 setenvif_module (shared)
 mime_module (shared)
 dav_module (shared)
 status_module (shared)
 autoindex_module (shared)
 info_module (shared)
 dav_fs_module (shared)
 vhost_alias_module (shared)
 negotiation_module (shared)
 dir_module (shared)
 actions_module (shared)
 speling_module (shared)
 userdir_module (shared)
 alias_module (shared)
 rewrite_module (shared)
 proxy_module (shared)
 proxy_balancer_module (shared)
 proxy_ftp_module (shared)
 proxy_http_module (shared)
 proxy_connect_module (shared)
 cache_module (shared)
 suexec_module (shared)
 disk_cache_module (shared)
 file_cache_module (shared)
 mem_cache_module (shared)
 cgi_module (shared)
 version_module (shared)
 perl_module (shared)
 php5_module (shared)
 proxy_ajp_module (shared)
 python_module (shared)
 ssl_module (shared)
Syntax OK

httpd . conf设置:

IfModule prefork.c>  ignore format on these tags
StartServers       8
MinSpareServers    5
MaxSpareServers   20
ServerLimit      256
MaxClients       256
MaxRequestsPerChild  4000
# worker MPM
StartServers         2
MaxClients         150
MinSpareThreads     25
MaxSpareThreads     75
ThreadsPerChild     25
MaxRequestsPerChild  0

使用https://code.google.com/p/check-httpd-limits/wiki/Documentation程序,我得到:

<>之前检查Apache Httpd MPM配置限制(版本2.4)作者Jean-Sebastien Morisset - http://surniaulula.com/Httpd二进制—配置:/etc/httpd/conf/httpd.conf—EXE:/usr/sbin/httpd—MPM: prefork—ROOT:/etc/httpd-版本:2.2Httpd进程—PID 10860 (httpd): 106.93 MB/3.95 MB共享- PID 13814 (httpd): 28.52 MB/6.36 MB共享[不包括平均值]—PID 13818 (httpd): 180.28 MB/4.29 MB共享—PID 13819 (httpd): 182.67 MB/4.04 MB共享—PID 13820 (httpd): 182.45 MB/4.08 MB共享—PID 13821 (httpd): 185.53 MB/4.04 MB共享—PID 13822 (httpd): 176.12 MB/4.36 MB共享—PID 13823 (httpd): 180.05 MB/4.04 MB共享—PID 13824 (httpd): 182.21 MB/4.05 MB共享—PID 13825 (httpd): 179.36 MB/4.04 MB共享—PID 20696 (httpd): 180.10 MB/4.04 MB共享—PID 20853 (httpd): 180.39 MB/4.03 MB共享—PID 20854 (httpd): 180.79 MB/4.04 MB共享—PID 21003 (httpd): 159.77 MB/4.05 MB共享- HttpdRealAvg: 166.09 MB[不包括共享]—HttpdSharedAvg: 4.05 MB- HttpdRealTot: 2225.76 MB[不包括共享]—HttpdRunning: 14Httpd配置—StartServers: 8—"ServerLimit":256—MinSpareServers: 5—MaxSpareServers: 20—MaxRequestsPerChild: 4000—MaxClients: 256服务器内存—已缓存:671.46 MB—"MemFree":547.88 MB—内存总量:3819.89 MB—SwapFree: 5951.89 MB—SwapTotal: 5951.99 MB计算结果汇总- OtherProcsMem: 370.74 MB (MemTotal - Cached - MemFree - HttpdRealTot - HttpdSharedAvg)- FreeMemNoHttpd: 3449.15 MB (MemFree + Cached + HttpdRealTot + HttpdSharedAvg)- maxlimitttpdmem: 42523.09 MB (HttpdRealAvg * MaxClients + HttpdSharedAvg)- AllProcsTotalMem: 42893.83 MB (OtherProcsMem + maxlimitttpdmem)MemTotal的最大值(3819.89 MB)StartServers 8 #(不变)默认为5(256 -> 21MinSpareServers 5 #(不变)默认值为5MaxSpareServers 20 #(未更改)默认值为10MaxRequestsPerChild 4000 #(不变)默认为10000MaxClients 21 # (256 -> 21) (MemFree + Cached + HttpdRealTot + HttpdSharedAvg)/HttpdRealAvg结果错误:AllProcsTotalMem (42893.83 MB)超过MemTotal (3819.89 MB)和free swap (5951.89 MB) 33122.05 MB。

Apache占用太多内存的原因有很多。虽然没有通用的"答案",但有一个故障排除列表:

  1. 重新安装Apache和所有模块。禁用所有你不需要的模块。除了可能使用额外的资源之外,这些还可能是安全隐患。
    1. mod_autoindex将允许任何人查看你的public_html目录下任何目录下的所有文件,只要没有索引。
    2. mod_alias将不仅会显示你正在运行Apache,但也将是一个很好的指标,你没有删除额外的模块,将使你更有可能成为目标。
    3. 删除所有代理模块,除非你实际使用它们。
    4. 删除所有你不需要的mod_cgi, mod_php等。您允许Apache执行的文件类型越多,恶意人员就有越多的方式进行恶意操作。
  • 检查服务器配置。不要害怕研究某些指令的作用,不要害怕创建apache.conf的备份并更改一些内容。最坏的情况是Apache将无法启动,或者Apache将崩溃。
  • 有时分配太多内存会产生内存问题。除非有特殊的原因将152M分配给PHP,否则这是很高的。把它降到32米或64米。如果一个特定的脚本需要更多,则只对该脚本启用它。

    接下来,检查数据库分配。通常,当有其他需要做的事情(比如查询调优)时,人们首先分配的是内存,以使某些事情运行得更快。

    从本质上讲,过多的分配会为I/O创建信息备份。听起来倒了,我知道。我也遇到过类似的问题,那就是资源的过度分配。将资源设置为默认值,看看这是否会改变内存使用情况。