FastCGI - 断开套接字管道或通过对等方重置连接(PHP5-FPM或php-fpm)

时间:2014-05-09 02:25:27

标签: php apache sockets fastcgi php-5.3

我遇到php-fpm的确定性问题。

每次向Web服务器发送大型GET请求时,php-fpm都会中断套接字连接,超过大约100KB。 Web服务器依次返回500内部服务器错误。 Apache错误日志显示(32)Broken pipe:

[Fri May 09 02:42:23 2014] [error] [client 127.0.0.1] (32)Broken pipe: FastCGI: comm with server "/usr/lib/cgi-bin/php5-fcgi" aborted: write failed

我知道应该使用POST而不是GET来实现这么大的请求,但是,由于我使用维基媒体软件作为wiki文本解析器,我无法控制它处理请求的方式,即GET方法。此外,由于文本很大,甚至达到1MB,我必须发送大型查询字符串。

这个问题吓坏了我!

我尝试将php-fpm调试级别更改为Error中的/etc/php5/fpm/php-fpm.conf,但与错误相关的NOTHING会记录到/var/log/php5-fpm.log。由于它中断了连接(打破了套接字管道),我至少期待一个错误日志。

我发现调试问题的方法是使用tcpflow分析连接包。 我清楚地看到php-fpm在TCP传输过程中中止连接,正好在它达到大约100K时。

谷歌搜索,我可以看到其他人遇到相关问题,但问题没有明确的答案,而且大多数人都是间歇性地遇到管道错误。

在我的情况下,它是确定性的,并在请求超过100KB时发生。

查看php-fpm配置文件,我没有看到对请求大小的任何限制。 我在Apache 2中运行php-fpm作为套接字(而不是主机)服务。

我该如何解决或解决这个问题?

php-fpm中是否有硬编码的东西在query_string超过100K时中止连接?这是参数吗?

让我相信它与PHP5-FPM完全相关的是,当我使用Apache模块实现PHP5时,它会处理大量请求。

我的配置:

marcelo@marcelo-VirtualBox:/usr/local/apache2/logs$ /usr/local/apache2/bin/apachectl -v
Server version: Apache/2.2.27 (Unix)
Server built:   May 10 2014 06:21:24
marcelo@marcelo-VirtualBox:/usr/local/apache2/logs$ 


marcelo@marcelo-VirtualBox:/usr/local/apache2/logs$ php -v
PHP 5.5.12 (cli) (built: May 10 2014 07:47:39) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
marcelo@marcelo-VirtualBox:/usr/local/apache2/logs$ 

*Apache2.conf:*

<IfModule mod_fastcgi.c>
    AddHandler php5-fcgi .php
    Action php5-fcgi /php5-fcgi
    Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
    #FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization -idle-timeout 300
    FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /tmp/php5-fpm.sock -pass-header Authorization -idle-timeout 300
</IfModule>

编辑1

为了添加问题,我在传递query_string时附加strace,其中text ='IT IS A TEST'。 (重复1000次(13KB大小))。任何人都可以使用任何PHP代码轻松复制这个。正如我所说,它不依赖于脚本,而只依赖于我传递一个大的query_string。

重要:

PID php-fpm: -p 8653 -p 8654 -p 8655 -p 8656

PID阿帕奇: -p 4178 -p 4562 -p 4563 -p 4564 -p 4565 -p 4566 -p 4567 -p 4568 -p 4570 -p 8425 -p 8426 -p 8427 < / p>

在命令的执行下方sudo strace -e trace=open,read,write,readv,writev,recv,recvfrom,send,sendto -s 999 -p 8653 -p 8654 -p 8655 -p 8656 -p 4178 -p 4562 -p 4563 -p 4564 -p 4565 -p 4566 -p 4567 -p 4568 -p 4570 -p 8425 -p 8426 -p 8427 2> ~/tmp/trace.txt

[pid  8427] write(10, "\1\1\0\1\0\10\0\0\0\1\0\0\0\0\0\0\1\4\0\1\0\35\0\0\20\vREDIRECT_HANDLERphp-fastcgi\1\4\0\1\0\24\0\0\17\3REDIRECT_STATUS200\1\4\0\1\0\24\0\0\t\tHTTP_HOSTlocalhost\1\4\0\1\0-\0\0\24\27HTTP_ACCEPT_ENCODINGgzip, deflate, compress\1\4\0\1\0\20\0\0\v\3HTTP_ACCEPT*/*\1\4\0\1\0L\0\0\17;HTTP_USER_AGENTpython-requests/2.2.1 CPython/2.7.3 Linux/3.11.0-20-generic\1\4\0\1\0B\0\0\4<PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\1\4\0\1\0\22\0\0\20\0SERVER_SIGNATURE\1\4\0\1\0007\0\0\17&SERVER_SOFTWAREApache/2.2.27 (Unix) mod_fastcgi/2.4.6\1\4\0\1\0\26\0\0\v\tSERVER_NAMElocalhost\1\4\0\1\0\26\0\0\v\tSERVER_ADDR127.0.0.1\1\4\0\1\0\17\0\0\v\2SERVER_PORT80\1\4\0\1\0\26\0\0\v\tREMOTE_ADDR127.0.0.1\1\4\0\1\0(\0\0\r\31DOCUMENT_ROOT/usr/local/apache2/htdocs\1\4\0\1\0\35\0\0\f\17SERVER_ADMINyou@example.com\1\4\0\1\0007\0\0\17&SCRIPT_FILENAME/usr/local/apache2/cgi-bin/php-fastcgi\1\4\0\1\0\22\0\0\v\5REMOTE_PORT50305\1\4\0\1\374\26\0\0\25\200\1\373\374REDIRECT_QUERY_STRINGaction=parse&text=IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+"..., 8192) = 8192
[pid  8656] read(3, "\1\1\0\1\0\10\0\0", 8) = 8
[pid  8427] write(10, "ST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+"..., 8192 <unfinished ...>
[pid  8656] read(3,  <unfinished ...>
[pid  8427] <... write resumed> )       = 8192
[pid  8656] <... read resumed> "\0\1\0\0\0\0\0\0", 8) = 8
[pid  8656] read(3, "\1\4\0\1\0\35\0\0", 8) = 8
[pid  8427] write(10, ".IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TE"..., 8192 <unfinished ...>
[pid  8656] read(3,  <unfinished ...>
[pid  8427] <... write resumed> )       = 8192
[pid  8656] <... read resumed> "\20\vREDIRECT_HANDLERphp-fastcgi", 29) = 29
[pid  8427] write(10, "T+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST"..., 8192) = 8192

**...**
**(THUS, PID 8427 (`APACHE`) WRITE THE FASTCGI PROTOCOL AND PASS THE LARGE QUERY_STRING...)**
**...**
**(NOW PID 8656 (`PHP-FPM`) JUMPS IN...READING THE FASTCGI PROTOCOL STREAM...)**
**...**

[pid  8656] read(3, "\1\4\0\1\0\24\0\0", 8) = 8
[pid  8656] read(3, "\17\3REDIRECT_STATUS200", 20) = 20
[pid  8656] read(3, "\1\4\0\1\0\24\0\0", 8) = 8
[pid  8656] read(3, "\t\tHTTP_HOSTlocalhost", 20) = 20
[pid  8656] read(3, "\1\4\0\1\0-\0\0", 8) = 8
[pid  8656] read(3, "\24\27HTTP_ACCEPT_ENCODINGgzip, deflate, compress", 45) = 45
[pid  8656] read(3, "\1\4\0\1\0\20\0\0", 8) = 8
[pid  8656] read(3, "\v\3HTTP_ACCEPT*/*", 16) = 16
[pid  8656] read(3, "\1\4\0\1\0L\0\0", 8) = 8
[pid  8656] read(3, "\17;HTTP_USER_AGENTpython-requests/2.2.1 CPython/2.7.3 Linux/3.11.0-20-generic", 76) = 76
[pid  8656] read(3, "\1\4\0\1\0B\0\0", 8) = 8
[pid  8656] read(3, "\4<PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 66) = 66
[pid  8656] read(3, "\1\4\0\1\0\22\0\0", 8) = 8
[pid  8656] read(3, "\20\0SERVER_SIGNATURE", 18) = 18
[pid  8656] read(3, "\1\4\0\1\0007\0\0", 8) = 8
[pid  8656] read(3, "\17&SERVER_SOFTWAREApache/2.2.27 (Unix) mod_fastcgi/2.4.6", 55) = 55
[pid  8656] read(3, "\1\4\0\1\0\26\0\0", 8) = 8
[pid  8656] read(3, "\v\tSERVER_NAMElocalhost", 22) = 22
[pid  8656] read(3, "\1\4\0\1\0\26\0\0", 8) = 8
[pid  8656] read(3, "\v\tSERVER_ADDR127.0.0.1", 22) = 22
[pid  8656] read(3, "\1\4\0\1\0\17\0\0", 8) = 8
[pid  8656] read(3, "\v\2SERVER_PORT80", 15) = 15
[pid  8656] read(3, "\1\4\0\1\0\26\0\0", 8) = 8
[pid  8656] read(3, "\v\tREMOTE_ADDR127.0.0.1", 22) = 22
[pid  8656] read(3, "\1\4\0\1\0(\0\0", 8) = 8
[pid  8656] read(3, "\r\31DOCUMENT_ROOT/usr/local/apache2/htdocs", 40) = 40
[pid  8656] read(3, "\1\4\0\1\0\35\0\0", 8) = 8
[pid  8656] read(3, "\f\17SERVER_ADMINyou@example.com", 29) = 29
[pid  8656] read(3, "\1\4\0\1\0007\0\0", 8) = 8
[pid  8656] read(3, "\17&SCRIPT_FILENAME/usr/local/apache2/cgi-bin/php-fastcgi", 55) = 55
[pid  8656] read(3, "\1\4\0\1\0\22\0\0", 8) = 8
[pid  8656] read(3, "\v\5REMOTE_PORT50305", 18) = 18
[pid  8656] read(3, "\1\4\0\1\374\26\0\0", 8) = 8
[pid  8656] read(3, "\25\200\1\373\374REDIRECT_QUERY_STRINGaction=parse&text=IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+A+TEST.IT+IS+"..., 64534) = 64534
**[pid  8427] read(10, 0x1528f20, 8192)   = -1 ECONNRESET (Connection reset by peer)**

**As can be seen, the connection is reset in the middle of transmission!!!**

解决

请参阅下面的答案。

1 个答案:

答案 0 :(得分:1)

fastcgi protocol规范的请求标头大小有限制。

最大大小为0xffff或~64KB。

由于 GET 方法在标头内传递查询字符串,无论您安装什么Web服务器,如果它实现了fastcgi协议,您将以错误结束(通常转换为500)。 / p>

解决方法是将请求方法更改为 POST ,前提是字符串位于邮件正文中,而不是标题。

这不是问题的解决方案,因为限制是&#34;硬编码&#34;在协议API上,但至少是一种解决方法。