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を使用してアダプティブスクエアを実装する方法の例

推薦する

vite2.0+vue3 モバイルプロジェクトの詳細な説明

1. 関連する技術的なポイントバイト版ヴュー3 ts統合ルーティングvuexを統合するAxiosを統...

JS が WeChat の「クソ爆弾」機能を実装

みなさんこんにちは、Qiufengです。最近、WeChatは新しい機能をリリースしました(WeCha...

CSS3 でテキストマーキーを実装するためのサンプルコード

背景何が起こったかというと、Luzhu は偶然、宇宙で最高の外部スピーカーを備えた携帯電話について知...

数千万のMySQLデータ量を素早くページ分割する方法

序文バックエンド開発では、一度に大量のデータがロードされ、メモリやディスク IO のオーバーヘッドが...

Linuxで中断されたシステムを呼び出す方法

序文低速システム コールとは、決して戻らない可能性があり、プロセスを永久にブロックするシステム コー...

設計仕様に準拠した設計は良い設計でしょうか?

これまでの数年間、私はいわゆる「設計仕様」についてかなりの数の執筆やコンサルティングを行ってきました...

画像を読み込むための JavaScript キャンバス

この記事では、画像を読み込むためのJavaScriptキャンバスの具体的なコードを参考までに紹介しま...

複数のサーバーにNginxリバースプロキシを実装する方法

Nginx は複数のサーバーをリバース プロキシします。つまり、nginx に異なるリクエストを送信...

オブジェクト指向の観点から Vue コンポーネントを理解するための簡単な分析

同じ関数や HTML コードが複数回使用される場合は、それらをコンポーネントに抽出することを検討でき...

MySql における特殊演算子の使用の概要

序文MySQL には次の 4 種類の演算子があります。算術演算子比較演算子論理演算子ビット演算子これ...

Linuxのpasswdコマンドの使用

1. コマンドの紹介passwd コマンドは、ユーザー パスワード、アカウント ロック、パスワードの...

JavaScript のスプレッド演算子とレスト演算子の違いの詳細な説明

目次レスト演算子とは何ですか? JavaScript 関数では REST 演算子はどのように機能しま...

CSS3を使用してトランジションとアニメーション効果を実現する

JS アニメーションの代わりに CSS アニメーションを使用する必要があるのはなぜですか? Java...

MySQL トランザクション制御フローと ACID 特性

目次1. ACIDの特性トランザクション制御構文3. トランザクション同時実行例外1. ダーティリー...

HTML テーブルの空白セル補完を実装する方法

私が初めて Web 開発を独学で学んだ頃は、いわゆる DIV/CSS レイアウトはなく、テーブル レ...