ホームページ >ウェブフロントエンド >jsチュートリアル >Node.js クラスターを理解する: 中心となる概念
PM2 を使用して Node.js プロセスを管理したことがある場合は、PM2 が クラスター モード をサポートしていることに気づいたかもしれません。このモードでは、Node.js で複数のプロセスを作成できます。クラスター モードのインスタンス数を max に設定すると、PM2 はサーバーで使用可能な CPU コアに対応する数のノード プロセスを自動的に作成します。
PM2 は、Node.js の Cluster モジュールを利用してこれを実現します。このモジュールは、従来、複数の CPU コアを利用する能力を制限していた Node.js のシングルスレッドの性質に対処します。しかし、Cluster モジュールは内部的にどのように動作するのでしょうか?プロセスはどのように相互に通信するのでしょうか?複数のプロセスが同じポートでリッスンするにはどうすればよいでしょうか?そして、Node.js はどのようにリクエストをこれらのプロセスに分散するのでしょうか?これらの質問に興味がある場合は、読み続けてください。
Node.js ワーカー プロセスは、child_process.fork() メソッドを使用して作成されます。これは、1 つの親プロセスと複数の子プロセスが存在することを意味します。コードは通常次のようになります:
const cluster = require('cluster'); const os = require('os'); if (cluster.isMaster) { for (let i = 0, n = os.cpus().length; i < n; i++) { cluster.fork(); } } else { // Start the application }
オペレーティング システムを勉強したことがある方は、おそらく fork() システム コールに精通しているでしょう。呼び出しプロセスは親であり、新しく作成されたプロセスは子です。これらの子プロセスは、親プロセスと同じデータ セグメントとスタックを共有しますが、物理メモリ空間は必ずしも共有されるわけではありません。 Node.js クラスターでは、マスター プロセスがポートでリッスンし、受信リクエストを ワーカー プロセスに分散します。これには、プロセス間通信 (IPC)、負荷分散戦略、およびマルチプロセス ポート リスニングという 3 つの主要トピックへの対応が含まれます。
マスター プロセスは、process.fork() を使用して子プロセスを作成します。これらのプロセス間の通信は、IPC チャネル を介して処理されます。オペレーティング システムは、次のようなプロセス間通信のためのいくつかのメカニズムを提供します。
メッセージパッシング
プロセスはメッセージを送受信することでデータを交換します。
セマフォ
セマフォは、システムによって割り当てられたステータス値です。制御を欠いたプロセスは、特定のチェックポイントで強制的に停止され、続行信号を待ちます。バイナリ値 (0 または 1) に限定される場合、このメカニズムは「ミューテックス」(相互排他ロック) として知られています。
パイプ
パイプは 2 つのプロセスを接続し、あるプロセスの出力を別のプロセスの入力として機能させることができます。これは、パイプ システム コールを使用して作成できます。 |シェル スクリプトのコマンドは、このメカニズムの一般的な例です。
Node.js は、親プロセスと子プロセス間の通信にイベントベースのメカニズムを使用します。以下は、親プロセスが TCP サーバー ハンドルを子プロセスに送信する例です:
const cluster = require('cluster'); const os = require('os'); if (cluster.isMaster) { for (let i = 0, n = os.cpus().length; i < n; i++) { cluster.fork(); } } else { // Start the application }
前述したように、すべてのリクエストは マスター プロセスによって分散されます。サーバーの負荷がワーカー プロセス間で均等に分散されるようにするには、負荷分散戦略が必要です。 Node.js はデフォルトで ラウンドロビン アルゴリズムを使用します。
ラウンドロビン方式は、Nginx でも採用されている一般的な負荷分散アルゴリズムです。これは、受信リクエストを各プロセスに順番に分散し、最初のプロセスから開始し、最後のプロセスに到達した後にループバックすることで機能します。ただし、この方法では、すべてのプロセスで処理能力が等しいことを前提としています。リクエストの処理時間が大きく異なるシナリオでは、負荷の不均衡が発生する可能性があります。
これに対処するために、Nginx はサーバーに異なる重みを割り当てる 加重ラウンドロビン (WRR) をよく使用します。最も高い重みを持つサーバーがその重みがゼロになるまで選択され、その時点で新しい重みシーケンスに基づいてサイクルが再開されます。
Node.js で負荷分散戦略を調整するには、NODE_CLUSTER_SCHED_POLICY 環境変数を設定するか、cluster.setupMaster(options) を介して構成します。マルチマシン クラスタ用の Nginx と、単一マシン マルチプロセスのバランシング用の Node.js クラスタを組み合わせるのが一般的なアプローチです。
Node.js の初期のバージョンでは、同じポートでリッスンしている複数のプロセスが受信接続を競合し、不均一な負荷分散を引き起こしていました。この問題は後にラウンドロビン戦略で解決されました。現在のアプローチは次のように機能します:
本質的に、マスター プロセスはポートをリッスンし、定義された戦略 (ラウンドロビンなど) を使用してワーカー プロセスに接続を分散します。この設計ではワーカー間の競合が排除されますが、マスター プロセスが非常に安定している必要があります。
この記事では、PM2 のクラスター モードをエントリ ポイントとして使用して、マルチプロセス アプリケーションを実装するための Node.js のクラスター モジュールの背後にある中心的な原則を検討しました。私たちは、プロセス間通信、負荷分散、マルチプロセス ポート リスニングという 3 つの重要な側面に焦点を当てました。
クラスター モジュールを学習すると、多くの基本原則とアルゴリズムが普遍的であることがわかります。たとえば、ラウンドロビン アルゴリズムは、オペレーティング システムのプロセス スケジューリングとサーバーの負荷分散の両方で使用されます。マスター ワーカー アーキテクチャは、Nginx のマルチプロセス設計に似ています。同様に、セマフォやパイプなどのメカニズムは、さまざまなプログラミング パラダイムで遍在しています。
新しいテクノロジーが継続的に登場しますが、その基礎は一貫しています。これらの核となる概念を理解することで、自信を持って新たな課題を推測し、適応できるようになります。
Leapcell は、Web ホスティング、非同期タスク、Redis 用の次世代サーバーレス プラットフォームです:
多言語サポート
無制限のプロジェクトを無料でデプロイ
比類のないコスト効率
効率化された開発者エクスペリエンス
簡単な拡張性と高いパフォーマンス
ドキュメントでさらに詳しく見てみましょう!
X でフォローしてください: @LeapcellHQ
ブログをお読みください
以上がNode.js クラスターを理解する: 中心となる概念の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。