并发用户导致的重负载导致502坏网关错误


Heavy load because of concurrent users causes 502 bad gateway error

我的服务器上安装了Nginx+PHP FPM。我们正在为30个并发用户长期加载服务器。

对于初始用户来说,它工作得很好,但一段时间后,它开始抛出502坏的网关错误。

我已经放置了一些nginx-php-fpm的日志和php-fpm的慢速日志。

php-fpm的慢日志中记录了一些条目,因为运行脚本和服务器上的负载时间过长。我认为这就是502坏网关错误的原因。但我不知道如何解决那个问题。

  • 为了解决这些错误,我需要在php-fpm.conf中进行哪些调整
  • 如何让nginx长时间等待php-fpm的响应
  • 如何增加php fpm的最大执行时间

这是所附的日志。

NGINX日志

2013/01/29 15:03:38[错误]2493#0:1046562 recv()在从上游读取响应标头时失败(104:对等方重置连接),客户端:49.248.0.2,服务器:****.com,请求:"GET MY_SCRIPT_URI HTTP/1.1",上游:"fastcgi://127.0.0.1:9000",主机:"****.com",引用人:"MY_SCRIPT_URL"

2013/01/29 15:03:39[错误]2493#0:1046561 recv()在从上游读取响应标头时失败(104:对等方重置连接),客户端:49.248.0.2,服务器:***.com,请求:"GET MY_SCRIPT_URI HTTP/1.1",上游:"fastcgi://127.0.0.1:9000",主机:"****.com",引用人:"MY_SCRIPT_URL"

有很多这种类型的错误,它们在整个文件中重复出现。

PHP FPM日志

[14-Feb-2013 12:54:13] ERROR: failed to ptrace(PEEKDATA) pid 10748: Input/output error (5)
[14-Feb-2013 12:54:18] ERROR: failed to ptrace(PEEKDATA) pid 10112: Input/output error (5)
[14-Feb-2013 12:54:18] ERROR: failed to ptrace(PEEKDATA) pid 12147: Input/output error (5)
[14-Feb-2013 12:54:19] ERROR: failed to ptrace(PEEKDATA) pid 30857: Input/output error (5)
[snip: many more]

PHP-FPM慢速日志

【2013年2月14日12:55:13】【pool www】pid 10748script_filename=MY_script_PATH[0x0007f446e8e06b0]curl_exec()MY_SCRIPT_PATH_1.php:317[0x0007f446e8e0490]调用服务()MY_SCRIPT_PATH_2:1331[0x0007f446e8e0148]转换为采购订单()MY_SCRIPT_PATH_3:15[0x0007fff0102b4d0]convertToPurchaseOrder()未知:0[0x0007f446e8de0d8]call_user_func_array()MY_SCRIPT_PATH_4:359[0x0007f446e8dd4d0]+++转储失败的

【2013年2月14日12:55:13】【pool www】pid 10117script_filename=MY_script_PATH[0x0007f446e8e06b0]curl_exec()MY_SCRIPT_PATH_1.php:317[0x0007f446e8e0490]调用服务()MY_SCRIPT_PATH_2:1331[0x0007f446e8e0148]convert()MY_SCRIPT_PATH_3:15[0x0007fff0102b4d0]convert()未知:0[0x0007f446e8de0d8]call_user_func_array()MY_SCRIPT_PATH_4:359[0x0007f446e8dd4d0]+++转储失败的

首先,30个并发用户的负载相当低——根据应用程序和硬件的不同,我预计会有更多。

读取slowlog时,您的应用程序似乎正在调用curl_exec()命令,并且该命令很慢。我猜发生的事情是,你的30个并发用户都在请求你的脚本;反过来,您的脚本在某个地方调用另一个web应用程序,该应用程序要么响应非常慢,要么完全超时(基于php.ini中的max_execution_time)。我不知道NGINX和php-FPM的来龙去脉,但我认为它启动的并发php实例数是最大的;由于这些实例都在等待CURL请求返回,NGINX无法再启动任何PHP实例,而是返回一个坏的网关。

我要考虑的第一件事是加快脚本的响应时间,可以异步运行CURL请求,也可以缓存它,或者找到另一种加速它的方法——运行同步CURL请求基本上意味着你的网站的性能和可扩展性完全取决于你调用的URL的性能和扩展性。

如果不能做到这一点,请将CURL的超时时间(php.ini中的max_execution_time)减少到5秒;这将导致您的一些CURL请求失败,但至少您的应用程序可以处理并更快地返回给用户;这也意味着等待的PHP线程要少得多。

据推测,有一种方法可以增加NGINX启动的PHP实例的数量;你可以处理这个问题,但你只是在轻微地解决问题——没有一个web服务器能够优雅地支持大量等待线程。