并发使用持久性PHP套接字

nat*_*iah 7 php sockets apache networking

我想使用PHP创建到通知服务服务器的持久套接字连接,我想知道有多少Apache/PHP线程能够在遇到问题之前同时使用套接字.我已经做了一些测试,但我似乎无法产生任何问题.


编辑

我正在使用这样的套接字:

$fh = pfsockopen('127.0.0.1', '1338');
fwrite($fh,$data);
Run Code Online (Sandbox Code Playgroud)

每个PHP线程都将共享相同的持久套接字

Mic*_*eim 25

限制fsockopen是系统内核设置中定义的最大打开文件描述符数量.如果pfsockopen实现良好,它应该只使用一个单个套接字连接,意味着每个php进程只有一个文件描述符.

你必须测试这个.

例如

$fd = pfsockopen('173.194.44.24', 80);
echo $fd;
Run Code Online (Sandbox Code Playgroud)

这将输出文件描述符的id: Resource id #1

在Web浏览器中打开它并重新加载页面 - 每次使用相同的套接字连接时,您应该看到相同的ID.

在默认的Apache prefork MPM - mod_php设置中,您可能会被随机发送到不同的分叉进程,这很可能导致n个不同的id循环,而n取决于您的Apache配置

  • MinSpareServers (<= n pConnections)
  • MaxSpareServers (> = n pConnections)
  • MaxRequestsPerChild (TMAX)

当你到达MaxRequestsPerChild进程终止并且这个孩子的持久连接也是如此.

在Apache Worker MPM或任何其他具有fastcgi功能的Web服务器(如Lighttpd或Nginx,结合PHP-FPM或PHP-cgi + fastcgi)中,我期待相同的行为,现在不是由Web服务器引起的,而是由php进程引起的.

与上述apache设置并行,相关设置是

PHP-FPM

  • pm.min_spare_servers (<= n pConnections)
  • pm.max_spare_servers (> = 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
Run Code Online (Sandbox Code Playgroud)

编辑

我忘了提到第二个限制.当然连接可以由服务器本身随时关闭.这在很大程度上取决于您使用的服务器设置和协议.

大多数服务器在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
Run Code Online (Sandbox Code Playgroud)

  • 哇,这是一个非常彻底和格式良好的解释.我希望答案基本上是这样,但我不确定我的测试结果.谢谢! (3认同)