NodeJS は、JavaScript を基盤とした開発プラットフォームで、開発者が JavaScript を使用してサーバーサイドアプリケーションを作成できるようにします。NodeJS の重要な特徴の一つは、シングルスレッドかつイベント駆動モデルで、多数の同時リクエストを効率的に処理できる点です。このモデルにより、複数のスレッドやプロセスを必要とせずに高いパフォーマンスを実現できます。
マスターワーカーパターンを使用する理由
しかし、NodeJS のシングルスレッドモデルには以下のような制限があります。
- CPU 集約型タスク:画像処理や暗号化/復号化などのタスクでは、シングルスレッドが他のリクエストをブロックし、パフォーマンスが低下する可能性があります。
- エラーハンドリング:エラーや例外が発生した場合、シングルスレッドがクラッシュするとアプリケーション全体が停止する恐れがあります。
- マルチコアの活用:シングルスレッドモデルでは、マルチコア CPU の性能を十分に活用することができません。
これらの問題を解決するために、NodeJS ではマスターワーカーパターン(またはクラスター・モード)を提供しています。この分散システムデザインパターンは、マスタープロセスと複数のワーカープロセスで構成されます。マスタープロセスがワーカーを管理・監視し、ワーカープロセスは特定のビジネスロジックを処理します。
マスターワーカーパターンの実装方法
NodeJS では、cluster
モジュールを使用してマスターワーカーパターンを簡単に実装できます。このモジュールは、複数の子プロセスを作成し、それらを制御・通信するためのメソッドやイベントを提供します。基本的な使用手順は次の通りです。
-
cluster
モジュールをインポートし、現在のプロセスがマスターかワーカーかを判定します。 - マスターであれば、
cluster.fork()
メソッドを使用して複数のワーカープロセスを作成し、イベントをバインドして状態やメッセージを監視します。 - ワーカーであれば、特定のビジネスロジックを実行し、
process.send()
を使用してマスタープロセスにメッセージを送信します。
基本的な使用例
以下は、cluster
モジュールを使用した基本的な例です。
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`マスター ${process.pid} が実行中です`);
// ワーカーをフォークする
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`ワーカー ${worker.process.pid} が終了しました`);
});
} else {
// ワーカーは任意のTCP接続を共有可能
// この場合はHTTPサーバー
http
.createServer((req, res) => {
res.writeHead(200);
res.end('ワーカーからの応答です!');
})
.listen(8000);
console.log(`ワーカー ${process.pid} が開始しました`);
}
このコードでは、マスタープロセスがcluster.isMaster
をチェックし、マスターである場合はシステムの CPU コア数分だけワーカーを作成します。各ワーカーはマスタープロセスの独立したインスタンスであり、それぞれが独自のメモリと V8 インスタンスを持ちます。ワーカーはhttp.createServer
を使用して HTTP サーバーを作成し、リクエストの待ち受けを開始します。
ワーカーがクラッシュまたは終了した場合、exit
イベントがトリガーされ、マスターがそのワーカーを再起動することが可能です。
高度な使用例:Nginx による負荷分散の統合
Nginx をリバースプロキシおよびロードバランサーとして使用することで、複数の Node.js プロセス間でリクエストを分散できます。
Nginx の設定例:
http {
upstream node_cluster {
server 127.0.0.1:8000;
server 127.0.0.1:8001;
server 127.0.0.1:8002;
# ... その他のNode.jsプロセス
}
server {
listen 80;
location / {
proxy_pass http://node_cluster;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
}
この設定では、Nginx がnode_cluster
内で定義された Node.js プロセス間でリクエストを均等に分散します。
マスターワーカーパターンを使用する利点
- 負荷分散:単一のサーバーで複数の Node.js プロセスを実行することで、リクエストが均等に分散され、スループットが向上します。
- フォールトトレランスと高可用性:ワーカーがクラッシュしても、マスターが他のワーカーに影響を与えずに再起動できます。
- CPU 集約型タスク:複数のワーカーが CPU 集約型タスクを処理することで、メインスレッドがブロックされるのを防ぎます。
注意点
- 状態の共有:各ワーカープロセスは独立しており、メモリを共有しません。アプリケーションが状態の共有(例:セッション状態)を必要とする場合は、外部サービスやデータベースを使用する必要があります。
結論として、Node.js のマスターワーカーパターンは、cluster
モジュールを通じて、マルチプロセスアプリケーションを簡単かつ効果的に構築できる方法を提供し、性能と信頼性を向上させます。
私たちはLeapcell、Node.jsプロジェクトのホスティングの最適解です
Leapcellは、Webホスティング、非同期タスク、Redis向けの次世代サーバーレスプラットフォームです:
複数言語サポート
- Node.js、Python、Go、Rustで開発できます。
無制限のプロジェクトデプロイ
- 使用量に応じて料金を支払い、リクエストがなければ料金は発生しません。
比類のないコスト効率
- 使用量に応じた支払い、アイドル時間は課金されません。
- 例: $25で6.94Mリクエスト、平均応答時間60ms。
洗練された開発者体験
- 直感的なUIで簡単に設定できます。
- 完全自動化されたCI/CDパイプラインとGitOps統合。
- 実行可能なインサイトのためのリアルタイムのメトリクスとログ。
簡単なスケーラビリティと高パフォーマンス
- 高い同時実行性を容易に処理するためのオートスケーリング。
- ゼロ運用オーバーヘッド — 構築に集中できます。
Xでフォローする:@LeapcellHQ