pconnect、クライアントが phpredis でサーバーに接続するために使用する API。
PHP プロセスが終了するまで、リクエストの終了時または終了時に接続は閉じられません。
API説明の原文です
そして次の質問が来ます:
1. PHP プロセスの終了とは、PHP 実行の完了を指しますか、それとも FPM の終了を指しますか?後者の場合、1回のPHP実行が完了してもredis接続は解放されず、次回実行時にredis接続が再利用されることになります。
2. close時に接続が閉じられないということは、pconnectを使用すると、コード内でclose()が呼ばれても接続は閉じられないということでしょうか?
これら 2 つの質問を踏まえて、実験を行って pconnect の機能を詳しく見てみましょう。
環境:
nginx + fpm
php5.3
fpm を
このようにして、ページリクエストは特定の fpm プロセスによって実行され、strace の追跡に便利です。
ページリクエストに対応するPHPコード:
リーリーコードの機能は非常にシンプルで、redis に接続し、最初に値を設定してからそれを取り出します。
感想:
strace を使用して fpm のシステム コールを観察します。接続のライフ サイクルが 1 回の PHP 実行である場合、ページが呼び出されるたびに、接続のライフ サイクルが 1 回である場合は、redis に接続するための connect システム コールが発生します。 fpm の終了後、最初のみ ページが呼び出されたときに connect システムコールが発生します。接続は後で再利用されるため、接続する必要はなく、コマンドリクエストを直接送信するだけです。
新しい fpm を開始します (プロセス番号 28082)。
実行
ページリクエストのシステムコールを記録します。下の写真に示すように:
プロセスが最初にソケット接続を確立したことがわかります (ファイル記述子は 9)。次に一連のコマンドを reids に送信し、最後に「this is test」という結果文字列を取得します。また、接続の終了に関連する redis コマンドやシステム コールはありません。 喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPtKzw+bH68fzveHK+Lrzo6zO0sPH1rTQ0DwvcD4NCjxwcmUgY2xhc3M9"brush:java;">
lsof -n -p 28082
fpm プロセスが 10.136.30.144 への reids 接続を維持しており、そのファイル記述子が 9 であることがわかります (これは strace の結果と一致しています)。
実行
リーリー 2 ページ目のリクエストのシステムコールを記録し、次の結果を取得します。
最初のリクエストとの違いは、接続を確立するプロセスが省略され、reids コマンドを直接送信して結果を取得することです。
次に、lsof -n -p 28082 を使用して、fpm によって開かれたファイル記述子を表示します。結果は上記のファイルと同じになります。
これは、接続が実際に再利用されており、新しく作成されたものではないことを示しています。
6 ページ目のリクエストを実行し (準備作業の構成により、この時点では fpm はすでに新しいプロセスです)、lsof を使用して、プロセスによって開かれたファイル記述子を表示します。
記述子 9 との reids 接続はまだ存在しますが、2 つの tcp 接続の一時ポートが異なっている、つまり接続が変更されていることがわかりました。
この時点で、質問 1 の結論に達します:
pconnect を使用する場合、接続のライフサイクルは 1 つの PHP 実行ではなく、fpm プロセスのライフサイクルです。 。
比較のために、まず見てみましょう。connect を使用して redis に接続し、redis->close() システム コールを呼び出します。 (上記コードのpconnectをconnectに変更し、最後にredis->close()を追加します)
接続の確立に加えて、プログラムの最後に quit コマンドが reids に送信され、接続されているファイル記述子が閉じられることがわかります。
次に、pconnect を使用した後の redis->close() のパフォーマンスを見てみましょう。 http://www.Bkjia.com/kf/yidong/wp/" target="_blank" class="keylink ">WPGJyIC8 +DQq0+sLrtffV+86qo7o8L3A+DQo8cHJlIGNsYXNzPQ=="ブラシ:java;">
$ip = 10.136.30.144;
$ポート = 7777;
$redis = 新しい Redis();
$redis->pconnect($ip, $port, 1);
$key = テスト;
$value = これはテストです。
$redis->set($key, $value);
$d = $redis->get($key);
var_dump($d);
$redis->close();
試す{
$redis->get($key);
}
catch (例外 $e){
echo $e->getMessage();
}
2回目のページリクエストを実行するシステムコールを直接見てみましょう
接続は確立されず、コマンドは結果を取得するために直接送信されます。接続が再利用されることを示します。同時に、quit コマンドは reids サーバーに送信されず、接続を閉じるためのシステムコールもありません。
ただし、ページリクエストの戻り結果には注意してください:
この時点で、質問 2 の結論に達します:
コード内で pconnect が使用されている場合、close の機能は現在の PHP が redis リクエストを行うのを防ぐことだけを目的としていますが、実際には長い redis 接続を閉じることはできません。接続は fpm が終了するまで後続のリクエストで再利用されます。プロセスのライフサイクル。
1. pconnect を使用する場合、接続のライフサイクルは 1 回の PHP 実行ではなく、fpm プロセスのライフサイクルになります。
2. コードで pconnect が使用されている場合、close の機能は現在の PHP が redis リクエストを行うのを防ぐことだけですが、実際には長い redis 接続を閉じることはできません。接続は終了するまで後続のリクエストで再利用されます。 fpm プロセスのライフサイクル。
。