我正在尝试在 VPS 上设置 Web 服务器。我的问题是,即使网站根本没有接收任何流量,php-cgi 进程的内存使用量也会随着时间的推移而增加。(它暂时位于防火墙后面)
该 VPS 有 360MB RAM。我使用的是 Debian Lenny 32bit 及其 lighttpd 和 php5-cgi 包。除了一些配置更改(如下所列)外,我使用的是 Debian 的默认设置。
该网站基于 Drupal。使用 Drupal 的 devel 模块,我可以看到 PHP 脚本的内存使用量平均小于 20KB,并且从未超过 8MB。
以下是输出的相关部分ps aux
:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
www-data 29871 0.0 1.7 54552 6368 ? Ss Aug12 0:00 /usr/bin/php-cgi
www-data 29873 0.0 7.4 65808 27468 ? S Aug12 0:00 /usr/bin/php-cgi
www-data 29874 0.0 3.7 55808 13736 ? S Aug12 0:00 /usr/bin/php-cgi
www-data 29875 0.0 4.3 58040 16204 ? S Aug12 0:00 /usr/bin/php-cgi
www-data 29876 0.0 4.4 57444 16288 ? S Aug12 0:00 /usr/bin/php-cgi
www-data 29877 0.0 1.7 54552 6368 ? Ss Aug12 0:00 /usr/bin/php-cgi
www-data 29879 0.0 9.6 67140 35684 ? S Aug12 0:26 /usr/bin/php-cgi
www-data 29880 0.0 6.6 59172 24492 ? S Aug12 0:23 /usr/bin/php-cgi
www-data 29881 0.0 7.1 59784 26388 ? S Aug12 0:22 /usr/bin/php-cgi
www-data 29882 0.0 7.4 60880 27440 ? S Aug12 0:23 /usr/bin/php-cgi
- php-cgi 这么大是正常的吗?
- 是否可以根据设置估算 php-cgi 内存使用情况?
- 有什么技巧可以减少 php-cgi 进程的内存消耗?
搜索已知的内存泄漏错误没有找到任何相关信息。如果默认的 Debian 软件包/配置有如此明显的内存泄漏,我会感到惊讶。同一主机上的其他用户没有遇到此问题。
到目前为止,我所做的就是将其设置PHP_FCGI_MAX_REQUESTS
为较低的值,以便快速回收 php-cgi 进程。当我用它ab
来模拟高负载时,这种方法非常有效。进程在增长到 10MB 以上之前会很快死亡。然而,在低到中等负载下,所有进程都会稳定增长(因为负载平衡),其中大多数进程同时消耗 28MB 以上,这使我的 VPS 面临交换风险。请注意,即使没有任何流量,进程也会稳定增长。
我可以减少 php-cgi 进程的数量,但这更像是一种变通方法,而不是修复方法。如果 php-cgi 通常像这样增长,我会感到惊讶。
另外,将 php-cgi 进程的 RSS 总数相加可得出:
$ ps -C php-cgi -o rss= | awk '{s+=$1}END{print s/1024}'
195.738
然而,free -m
给出以下输出:
total used free shared buffers cached
Mem: 360 351 8 0 33 190
-/+ buffers/cache: 127 232
Swap: 255 0 255
- 我是不是漏掉了什么?为什么使用的内存(不含缓冲区)低于主机上 php-cgi 进程的总驻留内存?
我有以下 PHP 扩展:
php5-cgi php5-通用 php5-curl php5-gd php5-mysql php5-xcache
xcache.size
设置为 24M。以前是 32M,但减少它没有帮助。xcache.var_size
设置为 0。其余插件使用库存配置。xcache 管理页面显示 xcache 使用的内存少于 1MB。
PHP 的memory_limit
设置为 32M。
这是我的 FastCGI 配置:
fastcgi.server = ( ".php" =>
((
"bin-path" => "/usr/bin/php-cgi",
"socket" => "/tmp/php.socket",
"max-procs" => 2,
"idle-timeout" => 20,
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "4",
"PHP_FCGI_MAX_REQUESTS" => "1000"
),
"bin-copy-environment" => (
"PATH", "SHELL", "USER"
),
"broken-scriptfilename" => "enable"
))
)
我或多或少使用的lighttpd.conf
是 Debian 附带的库存。
如果我可以提供任何其他数据,请告诉我。
任何帮助都非常感谢。我已经尝试解决这个问题好几天了。我已经没有主意了。
答案1
尝试降低 var_size。如果我们将值设置为 64MB,几个小时后它开始大量交换,接下来的几个小时后它完全关闭。尝试将原始设置保持在 32M,也许这应该对你有很大帮助 - 我们在我们的旅行网站 Xcache 仍然有很多有缺陷的软件 :(
答案2
设置最大请求数是正确的想法。这是防止系统 RAM 在发生内存泄漏时被填满的方法。
我建议你尝试切换到 apache + mod_php。如果这样可以且不会泄漏内存,则说明你的问题与 CGI 有关。如果使用 mod_php 时仍出现泄漏,则代码中可能存在内存泄漏。
您说您正在使用 Drupal。您安装了任何类型的 Drupal 模块吗?我怀疑 Drupal 的稳定版本在核心中是否存在内存泄漏,因此问题最有可能出现在模块和其他第三方附加组件和自定义中。
答案3
很多时候这些问题都是由于某些操作码缓存(例如 XCache)或 memcached PHP 扩展造成的。
答案4
从 /etc/php5/apache2/conf.d 中删除未使用的库。可能你不需要 pdo.ini 和 pdo_mysq.ini 或 mysqli.ini 这将节省几兆的内存