ホームページ > ウェブフロントエンド > jsチュートリアル > アプリをスピードアップするためのnode.jsクラスターを作成する方法

アプリをスピードアップするためのnode.jsクラスターを作成する方法

Joseph Gordon-Levitt
リリース: 2025-02-19 12:01:10
オリジナル
191 人が閲覧しました

How to Create a Node.js Cluster for Speeding Up Your Apps

コアポイント

  • node.jsは、イベント駆動型アーキテクチャと非ブロッキングI/O APIを備えた高トラフィックWebサイトを処理するための一般的なサーバー側の実行環境になり、非同期リクエスト処理を可能にします。
  • node.jsのスケーラビリティは、大企業が採用する重要な機能です。デフォルトで単一のスレッドで実行され、メモリ制限がありますが、node.jsはクラスターモジュールを介してアプリケーションを拡張して、単一のプロセスを複数のプロセスまたはワーカープロセスに分割できます。
  • node.jsクラスターモジュールは、同じnode.jsプロセスを複数回実行して動作します。これにより、メインプロセスを特定し、サーバーのハンドルを共有して親ノードプロセスと通信できるワーカープロセスを作成できます。
  • node.jsアプリケーションは、クラスターモジュールを使用して並列化でき、複数のプロセスを同時に実行できるようにします。これにより、システムの効率が向上し、アプリケーションのパフォーマンスが向上し、信頼性と稼働時間が向上します。
  • node.jsクラスターモジュールは主にWebサーバーに推奨されますが、ワーカープロセスとワーカープロセスとメインプロセス間の効果的な通信を慎重に検討する場合も、他のアプリケーションにも使用できます。

node.jsは、特に交通量の多いウェブサイトで、サーバー側の実行環境としてますます人気が高まっており、統計もこれを証明しています。さらに、多数のフレームワークが利用できるため、迅速なプロトタイピングに適した環境になります。 node.jsには、非ブロッキングI/O APIを使用してリクエストの非同期処理を可能にするイベント駆動型アーキテクチャがあります。 node.jsの重要でしばしば見落とされがちな機能は、そのスケーラビリティです。実際、これがいくつかの大企業がnode.js(Microsoft、Yahoo、Uber、Walmartなど)をプラットフォームに統合し、サーバー側の操作を完全にNode.js(Paypal、ebayなどに完全に移行する主な理由です。 、およびGroupon)。各node.jsプロセスは単一のスレッドで実行されます。デフォルトでは、32ビットシステムのメモリ制限は512MBで、64ビットシステムのメモリ制限は1GBです。メモリ制限は、32ビットシステムで約1GBに増加し、64ビットシステムで約1.7GBに増加させることができますが、メモリと処理能力は依然としてさまざまなプロセスのボトルネックになります。 node.jsが拡張アプリケーションに提供するエレガントなソリューションは、node.js用語の複数のプロセスまたはワーカープロセスに単一のプロセスを分割することです。これは、クラスターモジュールを介して実現できます。クラスターモジュールを使用すると、すべてのサーバーポートをメインノードプロセス(メインプロセス)と共有する子プロセス(作業プロセス)を作成できます。この記事では、node.jsクラスターを作成してアプリケーションを高速化する方法を学びます。

node.jsクラスターモジュール:それは何をし、どのように機能するか

クラスターは、親ノードプロセスの下で実行される同様のワーカープロセスのプールです。ワーカープロセスは、child_processesモジュールのfork()メソッドを使用して生成されます。これは、ワーカープロセスがサーバーのハンドルを共有し、IPC(インタープロセス通信)を使用して親ノードプロセスと通信できることを意味します。主なプロセスは、作業プロセスの開始と制御を担当します。メインプロセスで好きなだけ多くのワーカープロセスを作成できます。また、デフォルトでは、入ってくる接続が労働者プロセス(Windowsを除く)間でポーリングが割り当てられることを忘れないでください。実際、着信接続を割り当てる別の方法がありますが、ここでは議論しません。オペレーティングシステム(Windowsのデフォルト設定)への割り当てを引き渡します。 node.jsドキュメントでは、デフォルトのポーリングスタイルをスケジューリングポリシーとして使用することをお勧めします。クラスターモジュールを使用することは理論的には複雑に聞こえますが、その実装は非常に簡単です。使用を開始するには、node.jsアプリケーションに含める必要があります。

var cluster = require('cluster');
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
クラスターモジュールは、同じnode.jsプロセスを複数回実行します。したがって、最初に行う必要があるのは、メインプロセスに使用されるコードのどの部分と、ワーカープロセスにどの部分が使用されるかを決定することです。クラスターモジュールを使用すると、メインプロセスを次のように識別できます。

主なプロセスは、開始したプロセスであり、ワーカープロセスを初期化します。メインプロセスでワーカープロセスを開始するには、fork()メソッドを使用します:
if(cluster.isMaster) { ... }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この方法は、派生したワーカーに関するいくつかの方法とプロパティを含むワーカーオブジェクトを返します。次のセクションでいくつかの例をご覧ください。クラスターモジュールには複数のイベントが含まれています。ワーカープロセスの起動と終了の瞬間に関連する2つの一般的なイベントは、オンラインイベントと終了イベントです。ワーカープロセスがオンラインメッセージを導き出して送信すると、オンラインイベントが放出されます。労働者のプロセスが死ぬと、出口イベントが放出されます。その後、これら2つのイベントを使用して、労働者プロセスのライフサイクルを制御する方法を学びます。さて、私たちがこれまでに見たすべてをまとめて、完全に実行可能な例を示しましょう。
cluster.fork();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

このセクションには2つの例が含まれています。最初の例は、node.jsアプリケーションでクラスターモジュールを使用する方法を示す簡単なアプリケーションです。 2番目の例は、node.jsクラスターモジュールを利用するExpressサーバーです。これは、通常、大規模なプロジェクトで使用する本番コードの一部です。どちらの例もGithubからダウンロードできます。

node.jsアプリケーションでクラスターモジュールを使用する方法

この最初の例では、リクエストを処理するワーカープロセスIDを含むメッセージを使用して、すべての着信要求に応答する簡単なサーバーを設定します。主なプロセスは、4つのワーカープロセスを導き出します。各労働者プロセスでは、ポート8000​​を聴き始めて、着信リクエストを受け取ります。私が今説明したことを実装するコードは次のとおりです。

サーバー(コマンドノードSimple.jsを実行する)を起動し、URL

//m.sbmmt.com/link/link/link/link/link/link/link/link/link/link/link/link/link/link/link/link/link/link/linkにアクセスして、URLにアクセスできます。

高度にスケーラブルなExpressサーバーを開発する方法

Expressは、node.jsの最も人気のあるWebアプリケーションフレームワークの1つです(最も人気がない場合)。このウェブサイトで何度かカバーしました。もっと学習することに興味がある場合は、「Express 4を使用してRestful APIの作成」と「node.js駆動型チャットルームWebアプリケーション:Express and Azure」を読むことをお勧めします。 2番目の例は、高度にスケーラブルなExpressサーバーを開発する方法を示しています。また、単一のプロセスサーバーを移行して、少量のコードを使用してクラスターモジュールを利用する方法も示しています。

var cluster = require('cluster');
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この例への最初の追加は、node.js OSモジュールを使用してCPUコアの数を取得することです。 OSモジュールには、CPUコアの配列を返すCPUS()関数が含まれています。このアプローチを使用して、リソースの使用を最大化するために、サーバー仕様に基づいて導出するワーカープロセスの数を動的に決定できます。 2番目のより重要な追加は、作業プロセスの死に対処することです。ワーカープロセスが死ぬと、クラスターモジュールは出口イベントを発行します。イベントをリッスンし、放出されたときにコールバック関数を実行することで処理できます。これを行うには、cluster.on( 'exit'、callback)などのステートメントを書くことでできます。コールバック関数では、予想される労働者プロセスを維持するために新しいワーカープロセスを導き出します。これにより、未解決の例外がある場合でも、アプリケーションを実行し続けることができます。この例では、オンラインイベントのリスナーも設定します。これは、労働者のプロセスが導き出され、着信リクエストを受信する準備ができているときはいつでも放出されます。これは、ロギングまたはその他の操作に使用できます。

パフォーマンスの比較

APIをベンチマークするツールがいくつかありますが、ここではApacheベンチマークツールを使用して、クラスターモジュールの使用がアプリケーションのパフォーマンスにどのように影響するかを分析します。テストをセットアップするために、そのルートのルートとコールバック関数を備えたExpressサーバーを開発しました。コールバック関数で、仮想操作を実行し、短いメッセージを返します。サーバーには2つのバージョンがあります。1つはワーカープロセスがなく、すべての操作がメインプロセスで行われ、もう1つは8つのワーカープロセスがあります(マシンには8つのコアがあるため)。次の表は、マージクラスターモジュールが毎秒処理されるリクエストの数をどのように増やすかを示しています。

并发连接 1 2 4 8 16
单进程 654 711 783 776 754
8个工作进程 594 1198 2110 3010 3024

(1秒あたりの処理されたリクエストの数)

高度な操作

クラスターモジュールの使用は比較的簡単ですが、ワーカープロセスを使用して他の操作を実行できます。たとえば、クラスターモジュールを使用して、アプリケーションのゼロダウンタイムを(ほぼ!)ゼロダウンタイムを実現できます。しばらくの間、これらの操作のいくつかを行う方法を学びます。

主なプロセスとワーカープロセスとの間のコミュニケーション

時々、メインプロセスからメッセージをワーカープロセスに送信して、タスクを割り当てたり、他のアクションを実行したりする必要がある場合があります。その見返りに、労働者プロセスは、タスクが完了したことを主なプロセスに通知する必要がある場合があります。メッセージを聞くには、メインプロセスとワーカープロセスの両方でメッセージイベントのイベントリスナーを設定する必要があります。

ワーカーオブジェクトは、fork()メソッドによって返される参照です。作業プロセスのメインプロセスからのメッセージを聞くには:
var cluster = require('cluster');
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

メッセージは、文字列またはJSONオブジェクトにすることができます。特定のワーカープロセスにメッセージを送信するには、次のようなコードを記述できます。
if(cluster.isMaster) { ... }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

同様に、メインプロセスにメッセージを送信するには、次のことを書くことができます。

Node.jsでは、メッセージは汎用であり、特定のタイプがありません。したがって、メッセージタイプ、送信者、コンテンツ自体に関する情報を含むJSONオブジェクトとしてメッセージを送信することが最善です。たとえば、
cluster.fork();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここで注意すべきことの1つは、メッセージイベントコールバックが非同期に処理されていることです。定義された実行順序はありません。 GitHubのメインプロセスとワーカープロセスの間のコミュニケーションの完全な例を見つけることができます。
var cluster = require('cluster');
var http = require('http');
var numCPUs = 4;

if (cluster.isMaster) {
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
} else {
    http.createServer(function(req, res) {
        res.writeHead(200);
        res.end('process ' + process.pid + ' says hello!');
    }).listen(8000);
}
ログイン後にコピー

ゼロダウンタイム

var cluster = require('cluster');

if(cluster.isMaster) {
    var numWorkers = require('os').cpus().length;

    console.log('Master cluster setting up ' + numWorkers + ' workers...');

    for(var i = 0; i < numWorkers; i++) {
        cluster.fork();
    }

    cluster.on('online', function(worker) {
        console.log('Worker ' + worker.process.pid + ' is online');
    });

    cluster.on('exit', function(worker, code, signal) {
        console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
        console.log('Starting a new worker');
        cluster.fork();
    });
} else {
    var app = require('express')();
    app.all('/*', function(req, res) {res.send('process ' + process.pid + ' says hello!').end();})

    var server = app.listen(8000, function() {
        console.log('Process ' + process.pid + ' is listening to all incoming requests');
    });
}
ログイン後にコピー
ワーカープロセスを使用して達成できる重要な結果の1つは、(ほぼ)ゼロダウンタイムサーバーです。主なプロセスでは、アプリケーションを変更した後、ワーカープロセスを1つずつ終了および再起動できます。これにより、新しいバージョンのロード中に古いバージョンを実行できます。実行時にアプリケーションを再起動できるようにするには、2つのことを覚えておく必要があります。まず、主なプロセスは常に実行され、労働者プロセスのみが終了して再起動されます。したがって、メインプロセスを短く保ち、作業プロセスのみを管理することが重要です。第二に、労働者のプロセスを再開する必要があることを、どういうわけか主なプロセスに通知する必要があります。これを行うには、ユーザーの入力や監視ファイルの変更など、いくつかの方法があります。後者はより効率的ですが、メインプロセスで監視するファイルを識別する必要があります。ワーカープロセスを再起動することをお勧めします。以下に示すように、ワーカープロセスにシャットダウンメッセージを送信して、前者を実行できます。

そして、ワーカーメッセージイベントハンドラーの安全なシャットダウンを開始:

すべてのワーカープロセスに対してこれを行うには、クラスターモジュールの労働者プロパティを使用できます。これは、すべての実行中のワーカープロセスへの参照を保持します。また、すべてのワーカープロセスを再起動するときに呼び出すことができるメインプロセスの関数ですべてのタスクをラップすることもできます。

var cluster = require('cluster');
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

クラスターモジュール内のワーカーオブジェクトから、すべての実行中のワーカープロセスのIDを取得できます。このオブジェクトは、ワーカープロセスが終了および再起動されると、すべての実行中のワーカープロセスと動的に更新されることへの参照を保持します。最初に、WorkerIDSアレイにすべての実行中のワーカープロセスのIDを保存します。このようにして、新たに派生した労働者プロセスの再起動を避けます。次に、各労働者のプロセスを安全に閉鎖するように要求します。労働者のプロセスが5秒後も実行されていて、労働者のオブジェクトに存在する場合、労働者プロセスのキル機能を呼び出して、それを強制的に閉じます。 GitHubで実用的な例を見つけることができます。

結論

node.jsアプリケーションは、クラスターモジュールを使用して並列化して、システムをより効率的に使用できるようにすることができます。複数のプロセスを同時に実行できます。これにより、node.jsが難しい部品を処理するため、移行が比較的簡単になります。パフォーマンスの比較で実証したように、システムリソースをより効率的に活用することにより、アプリケーションのパフォーマンスを大幅に改善することができます。パフォーマンスに加えて、アプリケーションの実行中にワーカープロセスを再起動することにより、アプリケーションの信頼性と稼働時間を改善できます。つまり、アプリケーションでクラスターモジュールを使用することを検討する際には注意する必要があります。クラスターモジュールの主な推奨使用は、Webサーバー用です。それ以外の場合は、労働者プロセス間にタスクを割り当てる方法と、ワーカープロセスとメインプロセス間で進歩を効果的に伝える方法を詳しく調べる必要があります。 Webサーバーであっても、単一のnode.jsプロセスが、変更がエラーを導入する可能性があるため、アプリケーションに変更を加える前にボトルネック(メモリまたはCPU)であることを確認してください。最後になりましたが、node.jsのWebサイトは、クラスターモジュールの優れたドキュメントを提供しています。必ずチェックしてください!

Node.jsクラスター

に関する

faqs

node.jsクラスターを使用することの主な利点は何ですか?

node.jsクラスターを使用することの主な利点は、アプリケーションのパフォーマンスを改善することです。 node.jsはスレッドで実行されます。つまり、一度に1つのCPUコアのみを使用できることを意味します。ただし、最新のサーバーには通常、複数のコアがあります。 node.jsクラスターを使用することにより、それぞれが異なるCPUコアで実行されている複数のワーカープロセスを導出するメインプロセスを作成できます。これにより、アプリケーションはより多くの要求を同時に処理できるようになり、速度とパフォーマンスが大幅に向上します。

node.jsクラスターはどのように機能しますか?

node.jsクラスターは、複数のワーカープロセスを導出するメインプロセスを作成することで機能します。主なプロセスは、着信要求のために耳を傾け、投票方法でそれらを労働者プロセスに配布します。各ワーカープロセスは、個別のCPUコアで実行され、リクエストを個別に処理します。これにより、アプリケーションは利用可能なすべてのCPUコアを利用して、同時により多くのリクエストを処理できます。

node.jsクラスターを作成する方法は?

node.jsクラスターの作成には、node.jsが提供する「クラスター」モジュールの使用が含まれます。まず、「クラスター」と「OS」モジュールをインポートする必要があります。その後、「cluster.fork()」メソッドを使用して、ワーカープロセスを作成できます。 「OS.CPUS()。長さ」は、利用可能なCPUコアの数を提供します。これを使用して、作成するワーカープロセスの数を決定できます。簡単な例を次に示します:

var cluster = require('cluster');
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

node.jsクラスターでワーカープロセスのクラッシュに対処する方法は?

メインプロセスで「終了」イベントをリッスンすることにより、node.jsクラスターのワーカープロセスクラッシュを処理できます。ワーカープロセスがクラッシュすると、メインプロセスに「終了」イベントを送信します。その後、「cluster.fork()」メソッドを使用して、クラッシュしたワーカープロセスを置き換える新しいワーカープロセスを作成できます。例は次のとおりです。

if(cluster.isMaster) { ... }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

Express.jsでnode.jsクラスターを使用できますか?

はい、Express.jsでnode.jsクラスターを使用できます。実際、node.jsクラスタリングを使用すると、Express.jsアプリケーションのパフォーマンスが大幅に向上する可能性があります。 ClusterスクリプトのWorkerプロセスコードブロックにExpress.jsアプリケーションコードを配置するだけです。

node.jsクラスターの制限は何ですか?

node.jsクラスターはアプリケーションのパフォーマンスを大幅に改善できますが、いくつかの制限もあります。たとえば、労働者のプロセスは状態や記憶を共有しません。これは、すべてのワーカープロセスでアクセスできないため、セッションデータをメモリに保存できないことを意味します。代わりに、データベースやRedisサーバーなどの共有セッションストレージを使用する必要があります。

node.jsクラスターにバランスリクエストをロードする方法は?

デフォルトでは、node.jsクラスターの主なプロセスは、ポーリング方法で入っているリクエストを労働者プロセスに配布します。これにより、基本的な形式の負荷分散が提供されます。ただし、より高度なロードバランシングが必要な場合は、Nginxなどの逆プロキシサーバーを使用する必要がある場合があります。

制作でnode.jsクラスターを使用できますか?

はい、生産環境でnode.jsクラスターを使用できます。実際、生産環境でnode.jsクラスターを使用して、サーバーのCPUコアを最大限に活用し、アプリケーションのパフォーマンスを向上させることを強くお勧めします。

node.jsクラスターをデバッグする方法は?

node.jsクラスターのデバッグは、複数のワーカープロセスが同時に実行されているため、少し難しい場合があります。ただし、各ワーカープロセスに一意のポートを使用して、「検査」フラグを使用して各プロセスにデバッガーを添付できます。例は次のとおりです。

cluster.fork();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

他のnode.jsモジュールでnode.jsクラスターを使用できますか?

はい、他のnode.jsモジュールでnode.jsクラスターを使用できます。ただし、労働者のプロセスは状態やメモリを共有していないことに注意する必要があります。これは、モジュールが共有状態に依存している場合、クラスター環境では適切に機能しない可能性があることを意味します。

以上がアプリをスピードアップするためのnode.jsクラスターを作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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