PHP5-FPM随机开始消耗大量CPU - performance

我遇到了一个非常奇怪的问题,我不确定如何进一步调试。我有一个NGINX + PHP5-FPM + APC Amazon Ubuntu实例,上面安装了一个网站,它是一个复杂的PHP框架。在尝试调试问题时,我将流程简化为:包含许多大类,创建了主要对象,启动了会话,从memcached检索了配置数组,从memcached检索了XML文件,HTML包含模板,输出发送到客户端。

然后,我使用http_load工具将网站置于每秒20个请求的负载下:http_load -timeout 10 -rate 20 -fetches 10000 ./urls.txt

接下来发生的事情很奇怪。 top显示了一系列的php5-fpm进程,每个进程占用一些CPU,并且一切运行正常,如下所示:

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28440 www-data 20 0 67352 10m 5372 S 4.3 1.8 0:20.33 php5-fpm
28431 www-data 20 0 67608 10m 5304 S 3.3 1.8 0:16.77 php5-fpm
28444 www-data 20 0 67352 10m 5372 S 3.3 1.8 0:17.17 php5-fpm
28445 www-data 20 0 67352 10m 5372 S 3.0 1.8 0:16.83 php5-fpm
28422 www-data 20 0 67608 10m 5292 S 2.3 1.8 0:18.99 php5-fpm
28424 www-data 20 0 67352 10m 5368 S 2.0 1.8 0:16.59 php5-fpm
28438 www-data 20 0 67608 10m 5304 S 2.0 1.8 0:17.91 php5-fpm
28439 www-data 20 0 67608 10m 5304 S 2.0 1.8 0:23.34 php5-fpm
28423 www-data 20 0 67608 10m 5292 S 1.7 1.8 0:20.02 php5-fpm
28430 www-data 20 0 67608 10m 5300 S 1.7 1.8 0:15.77 php5-fpm
28433 www-data 20 0 67352 10m 5372 S 1.7 1.8 0:17.08 php5-fpm
28434 www-data 20 0 67608 10m 5292 S 1.7 1.8 0:18.56 php5-fpm
20648 memcache 20 0 51568 8192 708 S 1.3 1.3 2:51.06 memcached
28420 www-data 20 0 69876 13m 6300 S 1.3 2.3 0:20.89 php5-fpm
28421 www-data 20 0 67608 10m 5300 S 1.3 1.8 0:21.19 php5-fpm
28429 www-data 20 0 9524 2260 992 S 1.3 0.4 0:11.68 nginx
28435 www-data 20 0 67608 10m 5304 S 1.3 1.8 0:18.58 php5-fpm
28437 www-data 20 0 67352 10m 5372 S 1.3 1.8 0:17.87 php5-fpm
28441 www-data 20 0 67608 10m 5292 S 1.3 1.8 0:20.75 php5-fpm

然后经过一秒到几分钟之间的一段时间后,几个(通常是两个)php5-fpm进程突然消耗了所有CPU:

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28436 www-data 20 0 67608 10m 5304 R 48.5 1.8 0:23.68 php5-fpm
28548 www-data 20 0 67608 10m 5276 R 45.2 1.7 0:07.62 php5-fpm
28434 www-data 20 0 67608 10m 5292 R 2.0 1.8 0:23.28 php5-fpm
28439 www-data 20 0 67608 10m 5304 R 2.0 1.8 0:26.63 php5-fpm

此时,所有内容都会卡住,所有新的HTTP请求都将超时。如果我停止http_load工具,则php5-fpm会挂在那里很多分钟。有趣的是,如果我执行php5-fpm stop,则php5-fpm进程将消失,但是任何使用文件系统的命令都将在执行时出现问题。例如。如果我尝试通过ssh下载文件,top将显示以下内容,需要花费几分钟的时间来启动实际下载:

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3298 sshd 20 0 7032 876 416 R 75.2 0.1 0:04.52 sshd
3297 sshd 20 0 7032 876 416 R 24.9 0.1 0:04.49 sshd

PHP错误日志通常具有以下内容:

[05-Dec-2012 20:31:39] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 0 idle, and 58 total children
[05-Dec-2012 20:32:08] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 16 children, there are 0 idle, and 66 total children

Nginx错误日志充满了以下条目:

2012/12/05 20:31:36 [error] 4800#0: *5559 connect() to unix:/dev/shm/php-fpm-www.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: ..., server: ec2-....compute-1.amazonaws.com, request: "GET /usa/index.php?page=contact_us HTTP/1.0", upstream: "fastcgi://unix:/dev/shm/php-fpm-www.sock:", host: "ec2-....compute-1.amazonaws.com"

PHP-FPM慢日志没有显示任何有趣的内容,交换从未发生,并且我也没有收集有关该问题的其他有趣事实。我经历了许多配置文件更改的迭代,最近的是

nginx.conf:http://pastebin.com/uaD56hJF

pool.d / www.conf:http://pastebin.com/mFeeUULC

===更新1 ===

网站的配置:http://pastebin.com/qvinVNhB

===更新2 ===

还发现dmesg报告这样的错误

[6483131.164331] php5-fpm[28687]: segfault at b6ec8ff4 ip b78c3c32 sp bff551f0 error 4 in ld-2.13.so[b78b5000+1c000]

===更新3 ===

为了防万一,我们推出了一个新的Amazon EC2微型实例,以排除可能的硬件问题。另外,我现在正在使用php-fastcgi排除可能的fpm错误。其他差异很小,我认为唯一改变的是Ubuntu-> Debian。除了现在服务器设法在max_execution_time秒后稍微恢复(然后再次出现峰值)外,仍然发生相同的问题。

我尝试使用单独的test.php进行测试,但不确定是否是同一问题,但至少在top中它看起来相同。我创建了一个test.php,并包含了一堆属于我们框架的库。这些库除了定义类或包括其他定义类的库外,不执行任何其他操作。我检查了APC,并成功地为所有这些服务。我开始以每秒200个请求的速度向test.php加压,一段时间后发生了同样的事情。除了现在我设法得到一些错误,说“打开的文件太多”。虽然它并不总是发生的,但有时它只是开始超时而没有输出错误,并且一些php进程陷于消耗所有CPU的状态。我只玩了一点,但我认为这里存在相关性-通过控制包含的库数或请求/秒速率稍有变化,我可以控制何时会出现CPU峰值。我增加了相关的OS变量,但是问题仍然存在,尽管它花了更长的时间才发生(还请注意,我已将限制设置为比我在测试期间执行的请求总数大N倍的值)。

fs.file-max = 70000
...
*       soft    nofile   10000
*       hard    nofile  30000
...
worker_rlimit_nofile 10000;
...
(reloaded all the configs and made sure the new system vars actually took affect)

因此,到目前为止,我能提出的下一个最好的唯一的解释是,即使APC应该从内存中提取文件,在内部它也以一种在调用PHP include-s时仍使用文件描述符的方式实现。并且由于延迟释放它们或者在某个不幸的时刻同时有太多请求到达时,系统运行我们的描述符,新到达的HTTP请求很快被堆积到一个巨大的队列中。我将尝试以某种方式进行测试。

参考方案

我已经运行了一个具有类似配置的网站许多月,停机时间为零。我看过你的配置,看起来还可以。话虽如此,我很早以前就完成了配置。

我会考虑将pm.max_requests = 10000减少为更合理的内容,例如pm.max_requests = 500。这仅表示“不要将每个实例用于X个以上的请求”。最好不要将此数字设置得太高,因为这样做会使您对可能的PHP引擎错误有一定的弹性。

我认为真正的问题很可能在您的PHP脚本中。不知不觉很难说。

编辑:
考虑取消注释;request_terminate_timeout = 0并将其设置为类似request_terminate_timeout = 20的内容。然后,您的脚本将需要在20秒内完成。您很可能会看到行为发生变化,但我认为您的网站可能会继续存在。那将表明一个PHP脚本错误。

EDIT2:我自己的php-fpm配置如下:

[example.com]
listen = /var/run/sockets/example.com.socket
user = www-data
group = www-data
pm = dynamic
pm.start_servers = 5
pm.max_children = 15
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500
php_flag[expose_php] = off
php_flag[short_open_tag] = on

EDIT3:我在您的nginx配置中发现了意外情况,但这可能什么都不是。

您正在使用fastcgi_ignore_client_abort on;,这会在较旧版本的nginx下的工作进程中引起问题。我自己没有看到此问题,因为我正在运行最新版本的自定义编译。这是Nginx网站上问题的描述:

在1.0.2中,POST请求在以下情况下无法正确处理
fastcgi_ignore_client_abort设置为on可能导致工作人员
进程段错误。将fastcgi_ignore_client_abort切换回
默认(关闭)应该可以解决此问题。

JSoup Connection.userAgent被sun.net.www.protocol.http.HttpURLConnection击败 - java

显然,sun.net.www.protocol.http.HttpURLConnection将始终将“ Java /版本”附加到UserAgent。因此,JSoup Connection.userAgent无法将useragent设置为所需的值。无论如何,“ Java /版本”内容都会被追加。见Set user-agent property in https…

Java运算符性能算法与按位运算 - java

在真正影响性能的重复算术运算中,按位运算符会对性能产生正面还是负面影响?我尝试使用Google进行搜索,但无法获得确切的答案。例如我应该使用这个:int s = 15 << 4; 或这个:int s = 15 * 16; 来提高我的应用程序的性能。operator precedence也与性能相关吗? 参考方案 即使这些操作不是compile-t…

弹簧组件扫描不起作用 - java

Spring组件扫描似乎无法正常工作。我正在使用Spring 3.1和tomcat 7.0。这是我的applicationContext.xml的样子:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.spring…