Nginx + PHP-FPM 超时,几乎为零负载消耗?

Nginx + PHP-FPM 超时,几乎为零负载消耗?

我有一台在 Linode 上运行的服务器,上面装有 Ubuntu 10.04 LTS、Nginx 0.7.65、MySQL 5.1.41 和带有 PHP-FPM 的 PHP 5.3.2。

上面有一个WordPress博客,最近更新到WordPress 3.2.1。

我没有对服务器进行任何更改(除了更新 WordPress),虽然它运行良好,但几天前我开始出现停机。

我尝试解决这个问题,检查 error_log 后发现有很多超时和似乎与超时相关的消息。服务器当前正在记录此类错误:

2011/07/14 10:37:35 [warn] 2539#0: *104 an upstream response is buffered to a temporary file /var/lib/nginx/fastcgi/2/00/0000000002 while reading upstream, client: 217.12.16.51, server: www.example.com, request: "GET /page/2/ HTTP/1.0", upstream: "fastcgi://127.0.0.1:9000", host: "www.example.com", referrer: "http://www.example.com/"

2011/07/14 10:40:24 [error] 2539#0: *231 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 46.24.245.181, server: www.example.com, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "www.example.com", referrer: "http://www.google.es/search?sourceid=chrome&ie=UTF-8&q=example"

甚至看到了先前的 serverfault 讨论可能的解决方案:编辑/etc/php/etc/php-fpm.conf并更改

request_terminate_timeout=30s

代替

;request_terminate_timeout= 0

服务器工作了几个小时,然后又坏了。我再次编辑文件以保持原样,然后再次重新启动 php-fpm ( service php-fpm restart),但没有运气:服务器工作了几分钟,然后又一次又一次地出现问题。奇怪的是,虽然服务正在运行,但 htop 显示没有 CPU 负载(见图),我真的不知道如何解决这个问题。

在此处输入图片描述

配置文件在 pastebin 上

php-fpm.conf文件在这里

/etc/nginx/nginx.conf 在这儿

/etc/nginx/sites-available/www.example.com 在这儿

答案1

您是否尝试过在 nginx.conf 中不使用“upstream”,而是执行以下操作:

# Pass PHP scripts to PHP-FPM
location ~* \.php$ {
   try_files       $uri /index.php;
   fastcgi_index   index.php;
   fastcgi_pass    127.0.0.1:9000;
   include         fastcgi_params;
   fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
   fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
}

看看这里http://www.if-not-true-then-false.com/2011/nginx-and-php-fpm-configuration-and-optimizing-tips-and-tricks/

答案2

然后再次重新启动 php-fpm [...] 服务器工作了几分钟,然后又一次又一次出现问题

问题是 php-fpm 配置

但这不是超时问题。增加超时只会给 php 更多的时间来处理单个请求 - 这可能会掩盖症状,但不是正确的解决方案。

php-fpm 日志应该可以清楚地显示服务器出现问题的原因;根据我的经验(显然,在缺乏信息的情况下,这只是猜测),php-fpm 日志文件将包含如下条目:

#/var/log/php5-fpm.log
[19-Oct-2014 06:25:10] NOTICE: error log file re-opened
[19-Oct-2014 17:46:56] WARNING: [pool www] seems busy (you may need to increase
pm.start_servers, or pm.min/max_spare_servers), spawning 1 children, there are 
1 idle, and 5 total children
...

如果只有少数几个日志条目(如上所示),那问题不大。如果日志条目很多,且间隔只有几分钟或几秒钟,那么 php-fpm 就没有足够的资源来处理要求它处理的负载。

这并不罕见,因为标准 dist php-fpm 配置文件将包含类似这样的内容:

# /etc/php5/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

这意味着 php-fpm 将最多只能并行处理 5 个请求

尤其使用类似 wordpress 这样的程序,对于单个 html 页面,它会将大量后续请求(图像、css、js 文件等)也交给 php - 很容易形成大量且不断增加的请求队列,以至于对于任何给定的请求,它必须首先等待正在处理和已在等待的请求先得到处理。这会导致延迟(它将在任何浏览器分析工具中显示为等待时间)并经常导致大量超时。

还请注意,大量的 404(对不存在的任何内容的请求)是夸大任何服务器的局限性的简单方法 - 请检查并修复网站生成的任何 404。

如何修复

如果问题在于 php-fpm 运行的服务器进程太少,只需增加它们即可。要使用的数量取决于部署它的服务器的硬件;这里有一个建议:

# /etc/php5/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 20
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 15

这将允许并行处理 20 个请求 - 并且可以缓解任何问题而不会导致服务器陷入困境。

如果有疑问,更改 php-fpm 配置时需要遵循一个简单的规则:

  • 增加直到错误消息消失(并且性能可以接受)
  • 如果服务器内存不足或服务器负载不可接受,则减少:)

相关内容