Node.js でのクラスター作成に関する簡単な説明

Node.js でのクラスター作成に関する簡単な説明

クラスタ

Node.js のイベント ループやイベント レスポンス プロセッサはシングル スレッドであることはわかっていますが、最近の CPU は基本的にマルチコアです。最新の CPU のマルチコア特性を最大限に活用するには、複数の子プロセスが同じサーバー ポートを共有できるようにクラスターを作成します。

つまり、クラスターを通じて、複数の子プロセスを使用して同じポートの要求を処理できます。

http サーバーでクラスターを使用する簡単な例を見てみましょう。

定数cluster = require('cluster');
定数 http = require('http');
定数numCPUs = require('os').cpus().length;

クラスタがマスターの場合
  console.log(`メインプロセス ${process.pid} が実行中です`);

  // ワーカープロセスを生成します。
  (i = 0; i < numCPUs; i++) の場合 {
    クラスターをフォークします。
  }

  cluster.on('exit', (ワーカー、コード、シグナル) => {
    console.log(`ワーカープロセス ${worker.process.pid} が終了しました`);
  });
} それ以外 {
  // ワーカープロセスは任意の TCP 接続を共有できます。
  // この例では、HTTP サーバーが共有されます。
  http.createServer((req, res) => {
    書き込みヘッドを200にします。
    res.end('Hello World\n');
  }).listen(8000);

  console.log(`ワーカープロセス ${process.pid} が開始されました`);
}

クラスターの詳細

クラスター モジュールは lib/cluster.js から派生しています。cluster.fork() を使用して、メイン プロセスからのリクエストを処理する子ワーカー プロセスを作成できます。

クラスター内のイベント

クラスターは events.EventEmitter を継承するため、クラスターはイベントを送受信できます。

クラスターは、切断、終了、フォーク、リスニング、メッセージ、オンライン、セットアップの 7 つのイベントをサポートします。

切断について説明する前に、まず IPC という概念を紹介します。IPC の正式名称は Inter-Process Communication で、プロセス間通信を意味します。

IPC は主にメインプロセスとサブプロセス間の通信に使用されます。ワーカー プロセスは、作成後に自動的にマスター プロセスに接続します。 「disconnect」イベントが発行されると、接続は切断されます。

切断イベントをトリガーする理由は多数ありますが、worker.disconnect() へのアクティブな呼び出しや、ワーカー プロセスの終了または強制終了などが考えられます。

cluster.on('切断', (ワーカー) => {
  console.log(`ワーカープロセス #${worker.id} が切断されました`);
});

いずれかのワーカー プロセスが閉じられると、終了イベントがトリガーされます。これは通常、クラスター内のプロセスが異常終了するかどうかを監視するために使用されます。プロセスが終了した場合は、cluster.fork を使用して新しいプロセスを作成し、リクエストを処理するのに十分なプロセスがあることを確認します。

cluster.on('exit', (ワーカー、コード、シグナル) => {
  console.log('作業プロセス %d が終了しました (%s)。再起動しています...',
              worker.process.pid、シグナル || コード);
  クラスターをフォークします。
});

cluster.fork メソッドが呼び出されると、フォーク イベントがトリガーされます。

const タイムアウト = [];
関数 errorMsg() {
  console.error('接続エラー');
}

cluster.on('fork', (ワーカー) => {
  タイムアウト[worker.id] = setTimeout(errorMsg, 2000);
});

ワーカー プロセスが listen メソッドを呼び出すと、メイン プロセスとワーカー プロセスのリスニング イベントがトリガーされます。

cluster.on('listening', (ワーカー, アドレス) => {
  コンソール.log(
    `ワーカープロセスが ${address.address}:${address.port} に接続されました`);
});

Worker は作業スレッドを表し、address には address、port、addressType の 3 つの属性が含まれます。 addressType には 4 つのオプション値があります。

  • 4 (TCPv4)
  • 6 (TCPv6)
  • -1 (Unixドメインソケット)
  • 'udp4' または 'udp6' (UDP v4 または v6)

メインプロセスが子プロセスから送信されたメッセージを受信したときに、メッセージ イベントがトリガーされます。

メインプロセスがワーカープロセスを生成すると、フォークがトリガーされ、ワー​​カープロセスが実行されると、オンラインがトリガーされます。

setupMaster メソッドが呼び出されると、セットアップ イベントがトリガーされます。

クラスター内のメソッド

クラスターには、disconnect、fork、setupMaster という 3 つのメソッドがあります。

cluster.disconnect([コールバック])

クラスターの切断メソッドを呼び出すと、実際にはクラスター内の各ワーカーの切断メソッドが呼び出されます。これにより、ワーカーはメイン プロセスから切断されます。

すべてのワーカーが切断されると、コールバックが実行されます。

クラスター.fork([env])

fork メソッドは、メイン プロセスから新しい子プロセスを作成します。 env は、プロセス環境変数に追加されるキーと値のペアです。

fork はワーカー プロセスを表す cluster.Worker オブジェクトを返します。

最後のメソッドはsetupMasterです。

クラスター.setupMaster([設定])

デフォルトでは、クラスターは fork メソッドを使用して子プロセスを作成しますが、setupMaster を使用してこの動作を変更できます。設定変数を設定することで、後続のフォーク子プロセスの動作を変更できます。

setupMaster の例を見てみましょう。

定数cluster = require('cluster');
クラスター.setupMaster({
  実行: 'worker.js',
  引数: ['--use', 'https'],
  サイレント: 真
});
cluster.fork(); // https ワーカープロセス cluster.setupMaster({
  実行: 'worker.js',
  引数: ['--use', 'http']
});
cluster.fork(); // http ワーカープロセス

クラスター内の属性

クラスター オブジェクトを通じて、isMaster と isWorker を使用して、プロセスがメイン プロセスであるかどうかを判断できます。

現在のワーカー プロセス オブジェクトへの参照は、worker を通じて取得できます。

定数cluster = require('cluster');

クラスタがマスターの場合
  console.log('これがメインプロセスです');
  クラスターをフォークします。
  クラスターをフォークします。
} そうでない場合 (cluster.isWorker) {
  console.log(`これはワーカープロセス#${cluster.worker.id}です`);
}

アクティブなワーカー プロセス オブジェクトをワーカーを通じて走査できます。

// すべてのワーカー プロセスを反復処理します。
関数 eachWorker(コールバック) {
  (cluster.workers 内の定数 id) {
    コールバック(cluster.workers[id]);
  }
}
各ワーカー((ワーカー) => {
  worker.send('すべてのワーカープロセスに通知');
});

各作業者には ID 番号があり、それを使用して作業者の位置を特定します。

クラスター内のワーカー

ワーカー クラスには、ワーカー プロセスに関するすべての共通情報とメソッドが含まれています。 cluster.fork が生成するのはワーカー オブジェクトです。

ワーカー イベントはクラスター イベントと非常によく似ており、切断、エラー、終了、リスニング、メッセージ、オンラインの 6 つのイベントをサポートします。

ワーカーには、id、process、exitedAfterDisconnect の 3 つのプロパティが含まれます。

id はワーカーの一意の識別子です。

ワーカー内のプロセスは、実際には child_process.fork() を通じて作成される ChildProcess オブジェクトです。

プロセスはワーカー内のグローバル変数であるため、ワーカー内で直接プロセスを使用してメッセージを送信できます。

exitedAfterDisconnect は、ワーカー プロセスが .kill() または .disconnect() により終了した場合、値が true になることを意味します。他の手段で終了する場合、戻り値は false になります。ワーカー プロセスがまだ終了していない場合は未定義です。

アクティブな終了かパッシブな終了かを区別するには、worker.exitedAfterDisconnect を使用します。メイン プロセスは、この値に基づいてワーカー プロセスを再生成するかどうかを決定できます。

cluster.on('exit', (ワーカー、コード、シグナル) => {
  ワーカーが切断後に終了した場合 === true の場合 {
    console.log('これは自然終了なので、心配する必要はありません');
  }
});

// ワーカープロセスを終了します。
ワーカーを強制終了する

ワーカーは、send、kill、destroy、disconnect、isConnected、isDead の 6 つのメソッドもサポートします。

ここでは主にメッセージを送信する send メソッドについて説明します。

ワーカー.send(メッセージ[, sendHandle[, オプション]][, コールバック])

send メソッドと child_process の send メソッド パラメータは実際には非常に似ていることがわかります。基本的に、worker.send はマスター プロセスにあり、特定のワーカー プロセスにメッセージを送信します。 ChildProcess.send() と同等です。ワーカー プロセスでは、これによりマスター プロセスにメッセージが送信されます。 process.send() と同等です。

クラスタがマスターの場合
  ワーカーをクラスターにデプロイする
  ワーカー.send('hello');

} そうでない場合 (cluster.isWorker) {
  process.on('メッセージ', (msg) => {
    プロセス.send(メッセージ);
  });
}

上記の例では、メインプロセス内にいる場合は、worker.send を使用してメッセージを送信できます。子プロセスでは、ワーカー内のグローバル変数プロセスを使用してメッセージを送信できます。

要約する

クラスターを使用すると、マルチコア CPU の利点を最大限に活用できます。実際のプロジェクトに適用していただければ幸いです。

上記は、Node.js でクラスターを作成する詳細についての簡単な説明です。Node.js でクラスターを作成する方法の詳細については、123WORDPRESS.COM の他の関連記事をご覧ください。

以下もご興味があるかもしれません:
  • Nodejs のクラスター モジュールで複数のプロセス間でデータを共有する方法
  • Redis クラスタのデータシャーディングメカニズムの原理
  • Redis クラスター グラフィックス
  • Redis クラスターの紹介
  • Node.js のクラスター モジュールの詳細な解釈
  • ノード内のクラスターについての簡単な説明
  • node.js でクラスターを使用するチュートリアル
  • Node.jsはクラスタを使用してマルチプロセスを実装します

<<:  MySQL でストアド プロシージャを作成し、データ テーブルに新しいフィールドを追加する方法の分析

>>:  Windows 10 での Hyperledger Fabric 1.4 環境構築プロセスの図

推薦する

Vue で手ぶれ補正とスロットリングを使用する方法

目次序文コンセプト安定意味使用シナリオコードVueでの使用スロットリング意味使用シナリオコードVue...

Sitemesh チュートリアル - ページ装飾技術の原理と応用

1. 基本概念1. Sitemeshはページ装飾技術です。 1 : フィルターを通してページアクセス...

Linuxアカウントファイル制御管理の詳細な手順

Linux システムでは、ユーザーが手動で作成したさまざまなアカウントに加えて、システムまたはプログ...

MySQL 作成ルーチン権限に関する注意事項

1. ユーザーにルーチン作成権限がある場合は、プロシージャ | 関数を作成できます。 2. ユーザー...

新しいカーネルをLinuxシステムに移植する手順

1. ubuntu16.04 イメージと対応する ubuntu16.04 カーネル バージョンのソー...

MySQLのバックアップとリカバリの詳細な説明

序文:前回の記事では、さまざまな MySQL ステートメント構文の使用法とユーザー権限に関する知識を...

CSS3アニメーション属性に基づくWeChatタップアニメーション効果の実装

最近人気のWeChatタップ機能を見て、CSS3アニメーションを見直し、このボックスシェイクアニメー...

Javascript フロントエンド最適化コード

目次if判定の最適化1. 最も簡単な方法:判断2. より良い方法: スイッチ3. より良いアプローチ...

Vueは単一ファイルコンポーネントの完全なプロセス記録を実装します

目次序文単一ファイルコンポーネント基本概念シンプルなローダーコンポーネントコンテンツの解析コンポーネ...

Dockerコンテナの原理の分析

目次01 コンテナの本質とは何か? 02 Cgroupテクノロジーと名前空間テクノロジーの概要03 ...

仮想マシンの複製に関するVirtual Boxチュートリアル図

VMに慣れた後、BOXに切り替えるのは少し異なります。たとえば、コピーネットワークカードを2枚使って...

透明な入力ボックスにアイコンを追加する HTML コード

最近、弁護士推薦のウェブサイトを作成していたのですが、検索ボックスに問題がありました。検索ボックス内...

ウェブページが自動的にデュアルコアブラウザの高速モードを呼び出すようにします(Webkit)

コードサンプルヘッドタグにコード行を追加します: XML/HTML コードコンテンツをクリップボード...

CSS 共通スタイルで二重矢印を描画するサンプルコード

1. 単一の矢印への複数の呼び出し単一の矢印を実装したら、二重矢印を実装するのは簡単です。上では、単...

VUE 3 テレポート コンポーネントと使用構文をすぐに使い始める

目次1. テレポートの紹介1.1. 複数のテレポートを使用する2. テレポートを使用する理由3. テ...