Nodejs-cluster モジュールの知識ポイントの概要と使用例

Nodejs-cluster モジュールの知識ポイントの概要と使用例

面接官から「NodeJS で複数のプロセスを開始する方法を教えてください」と尋ねられることがあります。その場合、クラスター モジュールがすぐに頭に浮かぶはずです。では、クラスター モジュールの使用方法について詳しく見ていきましょう。

基本的な使い方

Node.js はデフォルトで単一プロセスとして実行され、32 ビット システムでは最大 512 MB のメモリ、64 ビット システムでは最大 1 GB のメモリを使用できます。マルチコア CPU を搭載したコンピュータの場合、1 つのコアのみが実行され、他のコアはアイドル状態になるため、これは非常に非効率的です。この問題を解決するために、クラスター モジュールが提案されています。

クラスター モジュールを使用すると、マスター プロセスと複数のワーカー プロセスを設定し、マスター プロセスでワーカー プロセスの操作を監視および調整できます。ワーカーはプロセス間通信を使用してメッセージを交換します。クラスター モジュールには、ラウンドロビン アルゴリズムを使用してワーカー プロセス間の負荷を調整するロード バランサーが組み込まれています。操作中、新しく確立されたすべてのリンクはメイン プロセスによって完了され、その後、メイン プロセスは指定されたワーカー プロセスに TCP 接続を割り当てます。

var クラスター = require('クラスター');
var os = require('os');

(クラスタがマスターの場合){
(var i = 0, n = os.cpus().length; i < n; i += 1){
クラスターをフォークします。
}
} それ以外 {
http.createServer(function(req, res) {
書き込みヘッドを200にします。
res.end("こんにちは世界\n");
}).listen(8000);
}

上記のコードは、まず現在のプロセスがマスタープロセスであるかどうかを判断します (cluster.isMaster)。マスタープロセスである場合は、CPU コアの数に応じて複数のワーカープロセスを作成します。そうでない場合は、現在のプロセスがワーカープロセスであることを意味し、プロセス内でサーバープログラムが起動されます。

上記のコードには、ワーカー プロセスがハングすると、メイン プロセスがそれを認識できないという欠点があります。この問題を解決するには、メイン プロセスにオンライン イベントと終了イベントのリスニング関数を展開します。

var クラスター = require('クラスター');
 
クラスタがマスターの場合
  var numWorkers = require('os').cpus().length;
  console.log('マスター クラスターが ' + numWorkers + ' 人のワーカーを設定しています...');
 
  for(var i = 0; i < numWorkers; i++) {
    クラスターをフォークします。
  }
 
  cluster.on('オンライン', function(ワーカー) {
    console.log('ワーカー ' + worker.process.pid + ' はオンラインです');
  });
 
  cluster.on('exit', 関数(ワーカー、コード、シグナル) {
    console.log('ワーカー ' + worker.process.pid + ' がコード: ' + code + '、シグナル: ' + signal で終了しました);
    console.log('新しいワーカーを開始しています');
    クラスターをフォークします。
  });
}

上記のコードでは、メイン プロセスがワーカー プロセスの終了イベントを監視すると、ワーカー プロセスが再起動されます。ワーカー プロセスが正常に開始され、正常に実行できるようになると、オンライン イベントが発行されます。

ワーカーオブジェクト

ワーカー オブジェクトは cluster.fork() の戻り値であり、ワーカー プロセスを表します。

その特性とメソッドは以下のとおりです。

(1)ワーカーID

worker.id は、現在のワーカーの一意のプロセス ID を返します。この番号は、cluster.workers 内の現在のプロセスを指すインデックス値でもあります。

(2)ワーカープロセス

すべてのワーカー プロセスは、child_process.fork() を使用して生成されます。 child_process.fork() によって返されたオブジェクトは、worker.process に格納されます。このプロパティを通じて、ワーカーが配置されているプロセス オブジェクトを取得できます。

(3) ワーカー.送信()

このメソッドは、メインプロセス内の子プロセスに情報を送信するために使用されます。

クラスタがマスターの場合
  var ワーカー = cluster.fork();
  ワーカー.send('こんにちは');
} そうでない場合 (cluster.isWorker) {
  process.on('メッセージ', 関数(msg) {
    プロセス.send(メッセージ);
  });
}

上記のコードの目的は、ワーカー プロセスがメイン プロセスによって送信されたすべてのメッセージをエコーすることです。

ワーカー プロセスでメイン プロセスにメッセージを送信するには、process.send(message); を使用します。メイン プロセスによって送信されたメッセージをリッスンするには、次のコードを使用します。

process.on('message', 関数(message) {
  console.log(メッセージ);
});

送信されるメッセージは、文字列または JSON オブジェクトになります。以下は JSON オブジェクトを送信する例です。

ワーカー.送信({
  タイプ: 'タスク 1'、
  差出人: 'マスター'、
  データ: {
    // 転送したいデータ
  }
});

cluster.workers オブジェクト

このオブジェクトはメイン プロセスでのみ使用可能であり、すべてのワーカー プロセスが含まれます。各メンバーのキー値はワーカー プロセス オブジェクトであり、キー名はワーカー プロセスの worker.id 属性です。

socket.on('data', 関数(id) {
  var ワーカー = cluster.workers[id];
});

クラスターモジュールのプロパティとメソッド

isMaster、isWorker です

isMaster プロパティは、現在のプロセスがマスター プロセスであるかどうかを示すブール値を返します。このプロパティは、process.env.NODE_UNIQUE_ID によって決定されます。process.env.NODE_UNIQUE_ID が未定義の場合、プロセスがメイン プロセスであることを意味します。

isWorker プロパティは、現在のプロセスがワーカー プロセスであるかどうかを示すブール値を返します。これは、isMaster プロパティの値の反対です。

フォーク()

fork メソッドを使用して新しいワーカー プロセスを作成し、コンテキストをメイン プロセスにコピーします。メインプロセスのみがこのメソッドを呼び出すことができます。

このメソッドはワーカー オブジェクトを返します。

殺す()

kill メソッドはワーカー プロセスを終了するために使用されます。システム信号を表す単一のパラメータを受け入れることができます。

現在のプロセスがメインプロセスである場合、worker.process との接続を終了し、システムシグナルメソッドをワーカープロセスに送信します。現在のプロセスがワーカー プロセスである場合、メイン プロセスとの通信を終了し、終了して 0 を返します。

以前のバージョンでは、このメソッドはworker.destroy() とも呼ばれていました。

リスニングイベント

ワーカー プロセスがリスニング メソッドを呼び出すと、「リスニング」イベントがプロセスのサーバーに送信され、次にメイン プロセスに送信されます。

このイベントのコールバック関数は 2 つのパラメータを受け入れます。1 つは現在のワーカー オブジェクト、もう 1 つは URL、ポート、アドレス タイプ (IPv4、IPv6、Unix ソケット、UDP) などの情報が含まれるアドレス オブジェクトです。これは、複数の URL を提供する Node アプリケーションに役立ちます。

中断せずにノードサービスを再起動する

サービスを再起動するには、サービスをシャットダウンしてから再度起動する必要があります。クラスター モジュールを使用すると、最初にワーカー プロセスを開始し、その後、元のワーカー プロセスをすべてシャットダウンできます。これにより、中断することなく Node サービスを再起動できるようになります。

まず、マスター プロセスはワーカー プロセスに再起動信号を送信します。

workers[wid].send({type: 'shutdown', from: 'master'});

ワーカー プロセスはメッセージ イベントをリッスンし、コンテンツがシャットダウンされていることを検出すると終了します。

process.on('message', 関数(message) {
  if(message.type === 'シャットダウン') {
    プロセス終了(0);
  }
});

以下は、すべてのワーカープロセスをシャットダウンする関数です。

関数restartWorkers() {
  var wid、ワーカーIds = [];
  for(wid in cluster.workers) {
    ワーカーIDをプッシュします。
  }
 
  ワーカーID.forEach(関数(wid) {
    クラスター.ワーカー[wid].send({
      テキスト: 'シャットダウン'、
      差出人: 'マスター'
     });
    setTimeout(関数() {
      クラスターワーカーの場合[wid] {
        クラスターワーカーをkill('SIGKILL');
      }
    }, 5000);
  });
};

PM2モジュール

PM2 モジュールは、クラスター モジュールをラップしたものです。その機能は、クラスター モジュールを可能な限り抽象化して、ユーザーが単一のプロセスを使用しているかのようにマルチプロセス Node アプリケーションを展開できるようにすることです。

// アプリ.js
var http = require('http');
 
http.createServer(function(req, res) {
  書き込みヘッドを200にします。
  res.end("こんにちは世界");
}).listen(8080);

PM2を使用してコマンドラインからこのコードを実行します。

$ pm2 スタート app.js -i 4

上記のコードの i パラメータは、このコードを cluster_mode で開始する必要があり、新しいワーカー プロセスの数は 4 であることを PM2 に伝えます。 i パラメータの値が 0 の場合、PM2 は現在のマシンの CPU コアの数に応じて複数のワーカー プロセスを開始します。

何らかの理由でワーカー プロセスが終了した場合、すぐに再起動されます。

# すべてのワーカープロセスを再起動する $ pm2 reload all

各ワーカー プロセスには ID があります。次のコマンドを使用して、単一のワーカー プロセスの詳細を表示できます。

$ pm2 show <ワーカーID>

ワーカー プロセスをシャットダウンするときに、次のコードを展開して、ワーカー プロセスがシャットダウン メッセージをリッスンできるようにすることができます。このメッセージを受け取ったら、最終的なクリーンアップ作業を完了して閉じてください。

process.on('メッセージ', 関数(msg) {
  if (msg === 'シャットダウン') {
    すべての接続を閉じる();
    ログを削除します。
    サーバーを閉じます。
    プロセス終了(0);
  }
});

Nodejs-cluster モジュールの知識ポイントと使用例のまとめはこれで終わりです。Nodejs-cluster モジュールの詳細については、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

<<:  ブラウザのバージョンを決定し、複数のブラウザと互換性があることを示すステートメント

>>:  CSSを使用してアダプティブスクエアを実装する方法の例

推薦する

MySQL における distinct と group by の違い

簡単に言うと、distinct は重複を削除するために使用され、group by は統計を集計するよ...

Google ブラウザのラベルと入力間のスペースに関する小さな問題

最初にコード、次にテキストコードをコピーコードは次のとおりです。 <!DOCTYPE html...

docker を使用して kafka プロジェクトをデプロイする Centos6 方法の分析

この記事では、Docker を使用して Centos6 に Kafka プロジェクトをデプロイする方...

コンピュータが予期せずシャットダウンした後、VMware で Linux がインターネットに接続できない問題の解決策

問題の説明: Linux システムのネットワーク カード ファイル /etc/sysconfig/n...

Centos8 (最小インストール) Python3.8+pip のインストール方法に関するチュートリアル

Python8のインストールを最小化した後、Python3.8.1をインストールしました。オンライン...

MySQL データベースを最適化する 8 つの方法の詳細な説明 (必読の定番)

導入:インターネット上にはデータベースの最適化に関する情報や方法が数多くありますが、その多くは品質に...

Mysql テーブルで利用可能な最小 ID 値を照会する方法

今日、研究室のプロジェクトを見ていたとき、私にとって「難しい」問題に遭遇しました。実は、それは私があ...

CSS 境界線の半分または部分的に表示される実装コード

1. 疑似クラスを使用して境界線の半分を表示する <!DOCTYPE html> <...

Nginx イントラネット スタンドアロン リバース プロキシの実装

目次1 Nginxのインストール2 Nginxの設定3 ホストファイルを変更する4 テストNginx...

データベースのデフォルトパスを変更した後にmysqlが起動できない問題の解決策

序文mysql がデフォルトのデータベース パスを変更したため、サービスを開始できませんでした。ログ...

Linux で SSH 経由でリモート ファイルシステムをマウントする方法の詳細な説明

SSHFS の機能: FUSE(Linux向けの最高のユーザー空間ファイルシステムフレームワーク)を...

Tomcat+Mysql の高同時実行構成の最適化の説明

1.Tomcatの最適化構成(1)Tomcatのcatalina.batを変更するJavaをサーバー...

Win10 64ビットMySQL8.0のダウンロードとインストールのチュートリアル図

公式サイトから MySQL をダウンロードしてインストールし、クライアントにログインするにはどうすれ...

MySQLワームレプリケーションの基本知識

ワームは、その名前が示すように、自ら複製し、その数は倍増、つまり指数関数的に増加します。 MySQL...

Linux での GDB 入門チュートリアル

序文gdb は Linux で非常に便利なデバッグ ツールです。コマンドライン モードのデバッグ ツ...