Node.jsクラスターモジュールの使用状況を詳細に分析する

php中世界最好的语言
リリース: 2018-05-24 09:52:15
オリジナル
1592 人が閲覧しました

今回は

Node.jsの使い方の詳細説明Node.jsのクラスターモジュールの使い方の注意点についてお届けします。 、見てみましょう。

クラスターモジュールの概要

nodeインスタンスはシングルスレッド操作です。サーバー側プログラミングでは、通常、システムのスループットを向上させるためにクライアント要求を処理するために複数のノード インスタンスが作成されます。このような複数のノード インスタンスをクラスターと呼びます。

ノードのクラスター モジュールを使用すると、開発者は元のプロジェクト コードをほとんど変更せずにクラスター サービスのメリットを得ることができます。

クラスターには以下の 2 つの一般的な実装ソリューションがあり、node に付属するクラスター モジュールは 2 番目のソリューションを採用しています。

オプション 1: 複数のノード インスタンス + 複数のポート

クラスター内のノード インスタンスはそれぞれ異なるポートをリッスンし、リバース プロキシが複数のポートへのリクエストの分散を実装します。

  1. 利点: 実装が簡単で、各インスタンスは比較的独立しているため、サービスの安定性に優れています。

  2. 短所: ポート占有の増加、プロセス間の通信がより面倒になります。

オプション 2: メイン プロセスはリクエストを子プロセスに転送します

クラスター内に、メイン プロセス (マスター) と複数の子プロセス (ワーカー) を作成します。マスターはクライアントの接続リクエストを監視し、特定のポリシーに従ってそれらをワーカーに転送します。

  1. 利点: 通常、占有されるポートは 1 つだけで、通信は比較的単純で、転送戦略はより柔軟です。

  2. 短所: 実装は比較的複雑で、メインプロセスの高い安定性が必要です。

入門例

クラスターモジュールでは、メインプロセスはマスターと呼ばれ、子プロセスはワーカーと呼ばれます。

例は次のとおりです。クライアントのリクエストを処理するために、同じ数の CPU を持つサーバー インスタンスを作成します。これらはすべて同じポートでリッスンしていることに注意してください。

// server.js
var cluster = require('cluster');
var cpuNums = require('os').cpus().length;
var http = require('http');
if(cluster.isMaster){
 for(var i = 0; i < cpuNums; i++){
  cluster.fork();
 }
}else{
 http.createServer(function(req, res){
  res.end(`response from worker ${process.pid}`);
 }).listen(3000);
 console.log(`Worker ${process.pid} started`);
}
ログイン後にコピー
バッチスクリプトを作成します: ./req.sh。

#!/bin/bash
# req.sh
for((i=1;i<=4;i++)); do  
 curl http://127.0.0.1:3000
 echo ""
done
ログイン後にコピー
出力は以下の通りです。ご覧のとおり、応答はさまざまなプロセスから送信されます。

ワーカーからの応答 23735

ワーカーからの応答 23731
ワーカーからの応答 23729
ワーカーからの応答 23730

クラスターモジュールの実装原理を理解する、主に 3 つの質問を理解する:

その方法マスターとワーカーはコミュニケーションを取りますか?

  1. 複数のサーバーインスタンスとのポート共有を実現するにはどうすればよいですか?

  2. 複数のサーバーインスタンス、クライアントからのリクエストを複数のワーカーに分散するにはどうすればよいですか?

  3. 以下は概略図を元に紹介します。ソースコードレベルの紹介は作者のgithubを参照してください。

  4. 質問 1: マスターとワーカー間のコミュニケーション方法

この質問は比較的単純です。マスター プロセスは、cluster.fork() を通じてワーカー プロセスを作成します。 Cluster.fork() は、child_process.fork() を通じて内部的に子プロセスを作成します。

言い換えると:

マスタープロセスとワーカープロセスは、親プロセスと子プロセスの関係です。

  1. マスタープロセスとワーカープロセスは、IPCチャネルを通じて通信できます。 (重要)

  2. 質問 2: ポート共有の実装方法

前の例では、複数のワーカーで作成されたサーバーが同じポート 3000 をリッスンしていました。一般に、複数のプロセスが同じポートをリッスンすると、システムはエラーを報告します。

なぜ私たちの例は大丈夫なのでしょうか?

その秘密は、listen()メソッドがネットモジュール内で特別に処理されていることです。現在のプロセスがマスター プロセスであるかワーカー プロセスであるかに応じて:

マスター プロセス: このポートで通常どおりリクエストをリッスンします。 (特別な扱いはありません)

  • worker进程:创建server实例。然后通过IPC通道,向master进程发送消息,让master进程也创建 server 实例,并在该端口上监听请求。当请求进来时,master进程将请求转发给worker进程的server实例。

  • 归纳起来,就是:master进程监听特定端口,并将客户请求转发给worker进程。

    如下图所示:

    问题3:如何将请求分发到多个worker

    每当worker进程创建server实例来监听请求,都会通过IPC通道,在master上进行注册。当客户端请求到达,master会负责将请求转发给对应的worker。

    具体转发给哪个worker?这是由转发策略决定的。可以通过环境变量NODE_CLUSTER_SCHED_POLICY设置,也可以在cluster.setupMaster(options)时传入。

    默认的转发策略是轮询(SCHED_RR)。

    当有客户请求到达,master会轮询一遍worker列表,找到第一个空闲的worker,然后将该请求转发给该worker。

    master、worker内部通信小技巧

    在开发过程中,我们会通过 process.on('message', fn) 来实现进程间通信。

    前面提到,master进程、worker进程在server实例的创建过程中,也是通过IPC通道进行通信的。那会不会对我们的开发造成干扰呢?比如,收到一堆其实并不需要关心的消息?

    答案肯定是不会?那么是怎么做到的呢?

    当发送的消息包含cmd字段,且改字段以NODE_作为前缀,则该消息会被视为内部保留的消息,不会通过message事件抛出,但可以通过监听'internalMessage'捕获。

    以worker进程通知master进程创建server实例为例子。worker伪代码如下:

    // woker进程
    const message = {
     cmd: 'NODE_CLUSTER',
     act: 'queryServer'
    };
    process.send(message);
    ログイン後にコピー

    master伪代码如下:

    worker.process.on('internalMessage', fn);
    ログイン後にコピー

    相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

    推荐阅读:

    设计模式的策略模式怎样在前端中使用

    如何对微信小程序进行开发

    以上がNode.jsクラスターモジュールの使用状況を詳細に分析するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    関連ラベル:
    ソース:php.cn
    このウェブサイトの声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
    最新の問題
    人気のチュートリアル
    詳細>
    最新のダウンロード
    詳細>
    ウェブエフェクト
    公式サイト
    サイト素材
    フロントエンドテンプレート