8

PHP を使用して、通知サービス サーバーへの永続的なソケット接続を作成したいと考えています。また、問題が発生する前にソケットを同時に使用できる Apache/PHP スレッドの数を知りたいと思っています。これでいくつかのテストを行いましたが、問題が発生するようには見えません。


編集

私はこのようなソケットを使用しています:

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

すべての PHP スレッドは、同じ永続的なソケットを共有します。

4

1 に答える 1

26

の制限fsockopenは、システムのカーネル設定で定義されているオープン ファイル記述子の最大量です。が適切に実装されている場合pfsockopen、単一のソケット接続のみを使用する必要があります。これは、php プロセスごとに 1 つのファイル記述子のみを意味します。

これをテストする必要があります。

例えば

$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(<= n pConnections)
  • MaxSpareServers (>= n pConnections)
  • MaxRequestsPerChild(tMax)

プロセスに到達MaxRequestsPerChildすると、この子の永続的な接続も終了します。

Apache Worker MPM、または Lighttpd や Nginx などの他の fastcgi 対応 Web サーバーと 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)

高速CGI

  • 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

編集

実は、2 つ目の制限について言及するのを忘れていました。もちろん、接続はサーバー自体によっていつでも閉じることができます。これは、使用しているサーバーの設定とプロトコルに大きく依存します。

ほとんどのサーバーは、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
于 2013-01-11T09:18:57.143 に答える