php - 并发使用持久化 PHP 套接字

标签 php apache sockets networking

我想使用 PHP 创建到通知服务服务器的持久套接字连接,我想知道在出现问题之前有多少 Apache/PHP 线程能够同时使用该套接字。我已经对此进行了一些测试,但似乎没有产生任何问题。


编辑

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

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

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

最佳答案

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

你必须测试这个。

例如

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

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

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

在默认的 Apache prefork MPM - mod_php 设置中,您可能会被随机发送到不同的 fork 进程,这很可能会导致 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 进程引起的。

与上面介绍的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

编辑

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

大多数服务器在 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

关于php - 并发使用持久化 PHP 套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14268018/

相关文章:

Apache 将子域重定向到文件夹,将文件夹作为子域处理

java - 使用 cassandra 数据库查询作为 Flink 程序的源

c# - 概念: Using WCF Service VS.套接字VS。

php - Amazon S3 - 405 方法不允许使用 POST(尽管我允许在存储桶上使用 POST)

php - 如何在 Drupal 中进行绝对重定向?

linux - 输出最后六个字符串

php - 如何确保JPEG图像有效并且可以被PHP处理?

Java服务器套接字通信非常慢

php - mysqli bind_param 不起作用 php

php - 使用 PHP 检查图像是否唯一的好方法是什么?