我遇到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!!!**
解决
请参阅下面的答案。
答案 0 :(得分:1)
fastcgi protocol
规范的请求标头大小有限制。
最大大小为0xffff或~64KB。
由于 GET 方法在标头内传递查询字符串,无论您安装什么Web服务器,如果它实现了fastcgi协议,您将以错误结束(通常转换为500)。 / p>
解决方法是将请求方法更改为 POST ,前提是字符串位于邮件正文中,而不是标题。
这不是问题的解决方案,因为限制是&#34;硬编码&#34;在协议API上,但至少是一种解决方法。