戴上你的眼镜--这将是一副很长的眼镜。
首先,我在做什么。我正在为一些特别慢的tcp设备构建一个web应用程序接口。向它们打开一个套接字需要200 to,而fwrite/fread循环则需要300 to。为了减少对每个请求的这两个操作的需要,我将打开一个持久的tcp套接字,该套接字将响应时间缩短了前面提到的200 To。我希望PHP能够共享来自不同客户端的请求之间的持久连接(确实如此!),但是在两天的交互、读取日志和修改设置之后,有些问题我无法解决。不过,我已经把范围缩小了。
设置:
相关配置:
nginx
php/pool.d.d
让我们从粗俗到细致入微地讲述所发生的事情。在重新开始之后,我有4x nginx进程和2xphp5-FPM进程等待处理请求。然后我每隔几秒钟向脚本发送请求。第一个需要一段时间打开套接字连接并以大约500‘s的速度返回数据,第二个以300’s返回数据(yay它正在重用套接字),第三个也在大约300‘s内成功,第四个请求= 502坏网关,与第5个相同。第六次请求再次返回数据,但现在它又花费了500 it。该过程重复几个周期,之后每4个请求就会产生2x502个坏网关和2x500ms的数据响应。
如果我将所有的fpm池值加倍,并让4xphp-FPM进程运行,那么循环就会出现4x成功的500 If响应,然后是4xBadGateway错误。如果我不使用持久套接字,这个问题就会消失,但是每个请求都是500 is。我怀疑持久套接字会阻止每个php-fpm进程空闲,并将其绑定起来,因此下一个进程将被选择,直到没有一个进程被留下,并且当它们出错时,它们可能被重新启动并在下一个循环中可用--套接字随进程一起死掉。我还没有检查“慢速日志”,但是nginx错误日志显示了很多这样的内容:
*188 recv()失败(104:从上游读取响应头时,客户端:.
互联网上所有关于修复nginx/php/502坏网关的建议都与高负载或fcgi_pass错误配置有关。这里不是这样的。增加缓冲区/大小,更改超时,为fcgi_pass从unix套接字切换到tcp,提高对system....none的连接限制在这里适用。
我在设置pm = ondemand而不是dynamic方面取得了一些其他成功,但是一旦初始fpm-进程在空转后被终止,所有随后的php-fpm派生程序都会失去持久套接字。对于php脚本,我使用带有stream_socket_client标志的STREAM_CLIENT_PERSISTENT ()。时间/流_select()循环检测套接字数据,fread($sock,4096)获取数据。显然,我不打电话给fclose()。
如果有人对如何获得持久套接字有一些额外的问题或建议,而不需要在请求完成之后绑定php进程,或者其他一些需要尝试的事情,我会很感激的。
一些有用的链接:
( Nginx + php-fpm“504网关超时”错误,负载几乎为零(在测试服务器上)
Nginx +PHP“错误104对等连接重置”导致偶尔重复发布“
http://www.linuxquestions.org/questions/programming-9/php-pfsockopen-552084/
https://stackoverflow.com/questions/14268018/concurrent-use-of-a-persistent-php-socket
http://devzone.zend.com/303/extension-writing-part-i-introduction-to-php-and-zend/#Heading3
https://stackoverflow.com/questions/242316/how-to-keep-a-php-stream-socket-alive
http://php.net/manual/en/install.fpm.configuration.php
发布于 2013-10-21 21:44:16
我在邮件列表上报道了这个问题。它最终成为了php中的一个bug,现在在git中解决了,应该在下一个php版本中,w00t!
如果有人感兴趣的话:https://groups.google.com/forum/#!topic/highload-php-en/qGu3Eaifj9s
https://serverfault.com/questions/545457
复制相似问题