ホームページ >PHPフレームワーク >Workerman >知っておくべき Workerman の属性recyclePort

知っておくべき Workerman の属性recyclePort

醉折花枝作酒筹
醉折花枝作酒筹オリジナル
2021-07-23 16:01:353073ブラウズ

Workerman は、純粋に PHP で開発されたオープンソースの高性能非同期 PHP ソケット フレームワークです。 TCP ロング接続と、WebSocket や MQTT などの多くのプロトコルをサポートします。今回はWorkermanのreusePort属性を紹介しますので、必要に応じて参照してください。

知っておくべき Workerman の属性recyclePort

Workerman は、高性能 PHP ソケット サーバー フレームワークです。 Workerman を使用して、TCP 層で直接プログラミングできます。基本的なプログラミング ルーチンは次のとおりです:

$w = new Workerman\Worker('tcp://0.0.0.0:80');
$w->count = 4;
$w->onMessage = function(Workerman\COnnection\TcpConnection $connection, array $data) {
    $connection->send('Hello World');
};
Worker::runAll();

使用プロセス中に、reusePort パラメータに注意を払ったかどうか疑問に思います。デフォルトでは # に設定されます。##false。このパラメータは何に使われるのでしょうか?パフォーマンスを向上させるには、どのような状況でこれを true に設定する必要がありますか?

1.reuseport の役割

reusePort パラメータに関して、Workerman の公式ドキュメントでは次のように説明されています:

リスニング ポートの再利用をオンにした後、無関係な複数のユーザーを許可します。関連するプロセスは同じポートをリッスンし、システム カーネルはロード バランシングを実行し、処理のためにソケット接続をどのプロセスに渡すかを決定します。これにより、サンダー ハーディング効果が回避され、マルチプロセスの短い接続アプリケーションのパフォーマンスが向上します。

Linux ネットワーク プログラミングを深く学習していない場合、この文を理解するのは困難です。以下に簡単に説明します。

サーバー プログラムは通常、サーバー上の特定のポート番号をリッスンすることによってクライアント要求を受信します。 Linux では、サーバーのネットワーク カードのポート番号は

Socket に抽象化されます。

一般的なサーバー プログラムでは、パフォーマンスを向上させるために、実行中に同じソケットをリッスンする複数のプロセス (通称

ワーカー) が存在し、クライアント接続が確立されない場合、これらのワーカーは一時停止状態になります。状態では、CPU リソースは消費されません。

クライアント接続が特定の瞬間に到着すると、Linux カーネルはこれらのワーカーを同時に起動し、接続の処理を競合させます。

結果として、ワーカーは 1 つだけになります。接続を処理する機会が得られます。他のワーカーは、競争が失敗した後も一時停止状態に戻り続けます。ワーカーをウェイクアップするプロセスでは CPU リソースが消費されます。ワーカーの数が増えると、より多くの CPU リソースが消費され、リソースの無駄が発生します。これは、

ショッキングな群れ効果と呼ばれることがよくあります。

「なぜ一度に 1 人のワーカーだけを目覚めさせないのですか?」と疑問に思うかもしれません。残念ながら、Linux カーネルにはそのような機能はありません。

幸いなことに、Linux 3.9 以降のバージョンでは、再利用ポート機能が追加されています。この機能の用途は何ですか?

reuseport を使用する前は、ポート番号は 1 つの Socket でしか監視できませんでしたが、reuseport を使用すると、この制限がなくなり、1 つのポート番号を複数の Socket で同時に監視できるようになります。

前述したように、Linux カーネルは一度に 1 つのワーカーだけを起動することはできませんが、カーネルは同じポートでリッスンしているソケットのグループにクライアント接続を均等に送信できます。

図に示すように、各ワーカーには独自のソケットがあり、すべて同じポートでリッスンします。クライアント接続が到着すると、カーネルはその接続をソケットに転送し、このソケットはそれが属するワーカーのみをウェイクアップします。これにより、

Thundering Herd Effect が巧みに解決され、全体的なパフォーマンスが向上します。

このことから、次のように結論付けることができます。Linux カーネルのバージョンが 3.9 以降の場合、Workerman を使用するときに、reusePort を true に設定すると、プログラムの実行効率が向上します。

2. Workerman が再利用ポートを使用する方法

Workerman でreusePort を

true に設定するだけで済みますが、Linux のこの高度な機能を活用できます。しかし、Workerman のソース コードでは、カーネル パラメータをオンにするだけでは済みません。 Workerman には多くのデザインの詳細が隠されています。見てみましょう。

Worker クラスは Workerman の最も重要なクラスであり、その中には listen() 関数があります:

protected function listen()
{
    ...
    if (!$this->_mainSocket) {
        ...
        $this->_mainSocket = stream_socket_server(...);
        ...
    }
    ...
}

listen () この関数の機能は、現在のプロセスにソケットを作成し、リクエストのリッスンを開始することです。

reusePort が

false の場合、メイン プロセスはワーカーを作成する前に listen() 関数を呼び出します。

protected function initWorkers() {
    ....
    if (!$worker->reusePort) {
        $worker->listen();
    }
    ....
}

その後、メイン プロセスは pcntl_fork を渡します。 () ワーカーを作成します。 pcntl_fork() には、親プロセスが作成した mainSocket を含め、作成された子プロセス (Worker) 内の変数が親プロセスからコピーされるという特徴があります。したがって、reusePort が **false** の場合、すべてのワーカーは親プロセスの mainSocket をコピーします。したがって、reusePort が**false** の場合、すべての Worker は親プロセスの _mainSocket をコピーします。つまり、1 つの Socket を共有します。

reusePort が

true の場合、状況は異なります。メイン プロセスは、ワーカーを作成する前に listen() を呼び出しません。代わりに、ワーカーの作成後に、各ワーカーが listen() 呼び出しを開始します:

protected static function forkOneWorkerForLinux($worker) {
    ...
    $pid = pcntl_fork();
    if ($pid === 0) {
        if ($worker->reusePort) {
            $worker->listen();
        }
        ...
    }
    ...
}

その結果、各子プロセス (ワーカー) が独自のソケットを作成します。

最後に、カーネルで再利用ポート機能を有効にしたい場合は、ソケット コンテキストを手動で設定する必要があります:

if ($this->reusePort) {
    $context = stream_context_create();
    stream_context_set_option($context, 'socket', 'so_reuseport', 1);
}

推荐学习:php视频教程

以上が知っておくべき Workerman の属性recyclePortの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。