并行使用持久PHP插座 [英] Concurrent use of a persistent PHP socket

查看:143
本文介绍了并行使用持久PHP插座的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


修改

我现在用的插座是这样的:

  $跳频= pfsockopen(127.0.0.1,1338);
FWRITE($ FH,$数据);

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


解决方案

的fsockopen 的限制是在系统内核设置定义的打开文件描述符的最大金额。如果 pfsockopen 实施好,它应该只使用一个单一的socket连接,意味着每个PHP进程只有一个文件描述符

您将不得不进行测试。

例如

  $ FD = pfsockopen(173.194.44.24,80);
回声$ FD;

这将输出的文件描述符的id:资源ID#1

在Web浏览器中打开这并重新加载页面几次 - 你应该看到相同的ID您使用的是同一个套接字连接每次

在默认的阿帕奇prefork MPM - mod_php的设置你可能被随机发送到很可能会导致在n个不同的ID,通过循环不同的分叉过程,同时ñ取决于你的Apache配置的


  • 的MinSpareServers (小于= N pConnections)

  • MaxSpareServers的(> = N pConnections)

  • MaxRequestsPerChild (TMAX)

当你达到 MaxRequestsPerChild 进程被终止,这个孩子的持久连接为好。

在一个Apache的工人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 ,并行持续连接<$ C $的最大金额C>ñpConnections

此模拟在命令行(PHP-CLI)

 #-a PHP
交互shell#在网络服务器环境中,这是一个孩子的等价PHP的&GT; $ FD1 =的fsockopen('google.de,80); #打开的非持久连接
PHP的&GT;回声$ FD1。 \\ n;
资源ID#1
PHP的&GT; $ FD2 =的fsockopen('google.de',80); #打开一个又一个
PHP的&GT;回声$ FD2。 \\ n;
资源ID#2#新的FD,新的连接PHP的&GT; $ PD1 = pfsockopen('google.de',80); # 持续连接
PHP的&GT;回声$ PD1。 \\ n;
资源ID#3#第一持久FD
PHP的&GT; $ PD2 = pfsockopen('google.de',80);
PHP的&GT;回声$ PD2。 \\ n;
资源ID#3#使用相同的连接PHP的&GT;退出#模拟MaxRequestsPerChild门槛
#-a PHP
交互shellPHP的&GT; $ PD3 = pfsockopen('google.de,80); #持久连接,同一主机
PHP的&GT;回声$ PD3。 \\ n;
资源ID#1#资源ID重复使用,因为所有旧的连接都消失了?

修改

真的遇到我忘了提第二个限制。
当然,连接可以随时通过服务器本身关闭。
这很大程度上取决于服务器设置和协议所使用。

大多数服务器关闭后, N 秒沉默之后 X 的总连接时间秒。

pconnect 处理这种默默的,它只是打开时,旧的走了一个新的连接。

在CLI再次模拟这样的:

 #-a PHP
交互shellPHP的&GT; $ PD1 = pfsockopen(127.0.0.1,80);
PHP的&GT;回声$ PD1。 \\ n;
资源ID#1
PHP的&GT; $ PD1 = pfsockopen(127.0.0.1,80);
PHP的&GT;回声$ PD1。 \\ n;
资源ID#1(重新启动在另一个控制台/etc/init.d/nginx重启我的web服务器)PHP的&GT; $ PD1 = pfsockopen(127.0.0.1,80);
PHP的&GT;回声$ PD1。 \\ n;
资源ID#2

I am wanting to use PHP to create a persistent socket connection to a notification service server and I am wondering how many Apache/PHP threads would be able to concurrently use the socket before I have problems. I have done some testing with this but I cannot seem to produce any problems.


Edit

I am using the socket like this:

$fh = pfsockopen('127.0.0.1', '1338');
fwrite($fh,$data);

Every PHP thread would share the same persistent socket

解决方案

The limitation with fsockopen is the maximum amount of open file descriptors defined in the systems kernel settings. If pfsockopen is implemented well, it should only use one single socket connection, means only one file descriptor per php process.

You'll have to test this.

e.g.

$fd = pfsockopen('173.194.44.24', 80);
echo $fd;

This will output the id of the file descriptor: Resource id #1

Open this in a web browser and reload the page several times - you should see the same id each time you are using the same socket connection.

In a default Apache prefork MPM - mod_php setup you probably are randomly sent to different forked processes which will most likely result in n different ids cycling through, while n depends on your Apache configuration of

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

When you reach MaxRequestsPerChild the process is terminated and the persistent connection on this child as well.

In a Apache Worker MPM or any other fastcgi-capable webserver like Lighttpd or Nginx combined with PHP-FPM or PHP-cgi + fastcgi I am expecting the same behavior, now not caused by the webserver but by the php processes.

In parallel to the apache settings described above, the relevant settings are

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)

In all configurations the maximum lifetime of a persistent connection is (in amount of requests handled by that process) tMax, the max amount of parallel persistent connections n pConnections

Simulating this on the command-line (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

EDIT

Acually I forgot to mention a second limitation. Connections of course can be closed anytime by the server itself. This heavily depends on the server settings and protocol you are using.

Most servers close a connection after n seconds of silence and after x seconds of total connection time.

pconnect handles this silently, it simply opens a new connection when the old one is gone.

Simulating this on cli again:

# 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

这篇关于并行使用持久PHP插座的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆