我想使用PHP创建一个持久的套接字连接到通知服务服务器,我想知道在出现问题之前有多少个Apache/PHP线程能够同时使用该套接字。我已经进行了一些测试,但是似乎无法产生任何问题。
编辑
我是这样使用套接字的:
$fh = pfsockopen('127.0.0.1', '1338');
fwrite($fh,$data);
每个PHP线程将共享相同的持久套接字
我想使用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
在Web浏览器中打开并重新加载页面数次 - 每次使用相同的套接字连接时应该看到相同的ID。
在默认的 Apache prefork MPM - mod_php 设置中,您可能会随机被发送到不同的分叉进程,这很可能会导致 n 个不同的ID循环,而 n 取决于您的 Apache 配置:
MinSpareServers
(≤ npConnections)MaxSpareServers
(≥ npConnections)MaxRequestsPerChild
(tMax)当达到MaxRequestsPerChild
时,该进程将终止,该子进程上的持久连接也将终止。
在 Apache Worker MPM 或任何其他支持快速cgi的web服务器(如 Lighttpd 或 Nginx)与 PHP-FPM 或 PHP-cgi + fastcgi 结合使用时,我期望看到相同的行为,现在不是由web服务器引起,而是由php进程引起。
与上述apache设置并行的相关设置为
PHP-FPM
pm.min_spare_servers
(≤ npConnections)pm.max_spare_servers
(≥ npConnections)pm.max_requests
(tMax)FastCGI
PHP_FCGI_CHILDREN
(= npConnections)PHP_FCGI_MAX_REQUESTS
(tMax)在所有配置中,持久连接的最大生存时间(由该进程处理的请求数)为tMax
,并发持久连接的最大数量为npConnections
在命令行(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