我想使用PHP创建到通知服务服务器的持久套接字连接,我想知道有多少Apache / PHP线程能够在遇到问题之前同时使用套接字。我已经做了一些测试,但我似乎无法产生任何问题。
修改
我正在使用这样的套接字:
$fh = pfsockopen('127.0.0.1', '1338');
fwrite($fh,$data);
每个PHP线程都将共享相同的持久套接字
答案 0 :(得分:25)
fsockopen
的限制是系统内核设置中定义的最大打开文件描述符数量。如果pfsockopen
实现良好,它应该只使用一个单一套接字连接,意味着每个php进程只有一个文件描述符 。
您必须对此进行测试。
e.g。
$fd = pfsockopen('173.194.44.24', 80);
echo $fd;
这将输出文件描述符的id:Resource id #1
在网络浏览器中打开并多次重新加载页面 - 每次使用相同的套接字连接时都会看到相同的ID。
在默认的 Apache prefork MPM - mod_php 设置中,您可能会被随机发送到不同的分叉进程,这很可能导致n个不同的id循环,而n取决于您的Apache配置
MinSpareServers
(< = n pConnections)MaxSpareServers
(> = n pConnections)MaxRequestsPerChild
(tMax)当你到达MaxRequestsPerChild
时,该过程终止并且该孩子的持久连接也是如此。
在Apache Worker MPM或任何其他支持fastcgi的网络服务器(如Lighttpd或Nginx,结合PHP-FPM或PHP-cgi + fastcgi)中,我期待相同的行为,现在不是由网络服务器引起的,而是由php进程引起的。< / p>
与上述apache设置并行,相关设置为
<强> PHP-FPM 强>
pm.min_spare_servers
(&lt; = n pConnections)pm.max_spare_servers
(&gt; = n pConnections)pm.max_requests
(tMax)<强>的FastCGI 强>
PHP_FCGI_CHILDREN
(= n pConnections)PHP_FCGI_MAX_REQUESTS
(tMax)在所有配置中,持久连接的最长生命周期是(以该进程处理的请求数量)tMax
,并行持久连接的最大数量n pConnections
在命令行上模拟这个(php-cli)
# php -a
Interactive shell # in a webserver environment this is the equivalent of one child
php > $fd1 = fsockopen( 'google.de', 80 ); # open non-persistent connection
php > echo $fd1 . "\n";
Resource id #1
php > $fd2 = fsockopen( 'google.de', 80 ); # open another one
php > echo $fd2 . "\n";
Resource id #2 # new fd, new connection
php > $pd1 = pfsockopen( 'google.de', 80 ); # persistent connection
php > echo $pd1 . "\n";
Resource id #3 # first persistent fd
php > $pd2 = pfsockopen( 'google.de', 80 );
php > echo $pd2 . "\n";
Resource id #3 # uses the same connection
php > exit # simulating MaxRequestsPerChild threshold
# php -a
Interactive shell
php > $pd3 = pfsockopen( 'google.de', 80 ); # persistent connection, same host
php > echo $pd3 . "\n";
Resource id #1 # resource id reused because all old connections are gone
修改强>
我忘了提到第二个限制。 当然连接可以由服务器本身随时关闭。 这在很大程度上取决于您使用的服务器设置和协议。
大多数服务器在n
秒静默后以及总连接时间x
秒后关闭连接。
pfsockopen
以静默方式处理此问题,它只是在旧连接消失时打开一个新连接。
再次在cli上模拟这个:
# php -a
Interactive shell
php > $pd1 = pfsockopen( '127.0.0.1', 80 );
php > echo $pd1 . "\n";
Resource id #1
php > $pd1 = pfsockopen( '127.0.0.1', 80 );
php > echo $pd1 . "\n";
Resource id #1
(restarting my webserver on the another console /etc/init.d/nginx restart)
php > $pd1 = pfsockopen( '127.0.0.1', 80 );
php > echo $pd1 . "\n";
Resource id #2