ホームページ > 記事 > ウェブフロントエンド > Nodejs の配布方法
インターネット アプリケーションの継続的な開発に伴い、単一のサーバーで高い同時実行性と大規模なトラフィックのニーズを満たすことが困難になることがよくあります。この問題を解決するために、分散システムが登場しました。 Node.js は非常に人気のあるサーバーサイド JavaScript 実行環境であり、イベント駆動型のノンブロッキング I/O モデルを使用し、高同時実行性と高スループットのリクエストを処理できます。ただし、単一の Node.js プロセスの処理能力には依然として限界があります。そこでこの記事では、Node.jsを使った分散システムの実装方法を紹介します。
分散とは、タスクを複数のサブタスクに分解し、これらのサブタスクを実行のために異なる作業ノードに割り当て、ネットワーク通信を通じてタスク全体を共同で完了することを指します。 Node.js で分散システムを実装するには主に 2 つの方法があります。1 つはマルチプロセス モードを使用する方法、もう 1 つはメッセージ キューを使用する方法です。
1. マルチプロセス モードを使用する
Node.js は、組み込みの child_process モジュールを通じて子プロセスを作成するための API を提供します。同じタスクを同時に処理する複数の子プロセスを簡単に作成できます。 。マルチプロセスモードでは、各サブプロセスが独立しており、IPC(プロセス間通信)を介してサブプロセス間でデータが交換されます。
マスター-ワーカー モードは、最も古典的なマルチプロセス モードの 1 つです。このモードでは、マスター プロセスと複数のワーカー プロセスが存在します。マスター プロセスは、開始、停止、再起動などを含むすべてのワーカー プロセスの管理を担当し、ワーカー プロセスは特定のリクエストまたはタスクの処理を担当します。
Node.js では、クラスター モジュールを通じてマスター/ワーカー モードを実装できます。クラスター モジュールは、child_process モジュールに基づいてカプセル化された高度なモジュールであり、以下に示すように、マスター/ワーカー モードを簡単に実装できます:
const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); // 当主进程被终止时,关闭所有工作进程 process.on('SIGINT', () => { console.log('Received SIGINT. Shutting down workers...'); for (const id in cluster.workers) { cluster.workers[id].kill(); } }); // 根据CPU数量创建工作进程 for (let i = 0; i < numCPUs; i++) { cluster.fork(); } // 当有工作进程被断开连接(崩溃)时,自动重新启动 cluster.on('exit', (worker, code, signal) => { console.log(`Worker ${worker.process.pid} died`); cluster.fork(); }); } else { console.log(`Worker ${process.pid} started`); // Workers可以处理具体的任务,例如下面是创建HTTP服务器的代码 http.createServer((req, res) => { res.writeHead(200); res.end('Hello from worker!'); }).listen(3000); }
上記のコードは、クラスター モジュールを使用してマスター プロセスを作成する方法を示しています。実際の使用では、特定のタスクや HTTP サーバーなどのビジネス ロジックをワーカー プロセスに組み込んで実行できます。
プロセス プール モードは、より効率的なマルチプロセス モードです。このモードでは、すでに作成されたプロセスを再利用してパフォーマンスの最適化を実現できます。一般に、プロセス プール内のプロセスの数は、高負荷時にも要求を確実に満たせるように、システム CPU の数に応じて動的に調整する必要があります。
Node.js には組み込みプロセス プール モジュールがありませんが、サードパーティ モジュールを通じて実装できます。たとえば、以下に示すように、generic-pool モジュールを使用してワーカー プロセス プールを簡単に実装できます。
const http = require('http'); const pool = require('generic-pool'); const numCPUs = require('os').cpus().length; const workerFactory = { create: function() { return new Promise(resolve => { const worker = child_process.fork('./worker.js'); worker.once('message', msg => { if (msg.ready) { resolve(worker); } }); }); }, destroy: function(worker) { return new Promise(resolve => { worker.once('exit', () => { resolve(); }); worker.send('exit'); }); } }; const workerPool = pool.createPool(workerFactory, { max: numCPUs }); // 创建HTTP服务器 http.createServer(async (req, res) => { const worker = await workerPool.acquire(); worker.send({ type: 'request', path: req.url }); worker.once('message', msg => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(msg)); workerPool.release(worker); }); }).listen(3000);
上記のコードは、generic-pool モジュールを使用してワーカー プロセス プールを作成し、呼び出しを行う方法を示しています。 HTTP サーバー内のプロセス プール内のワーカーは特定のリクエストを処理します。
2. メッセージ キューの使用
メッセージ キューは、非同期 (ノンブロッキング) 通信モードに基づく分散通信メカニズムです。メッセージ キュー モードでは、メッセージをキューに送信でき、受信側はキューからメッセージを取得して処理します。したがって、メッセージキューは、分散システムにおけるタスク分散やデータ送信などの問題を解決し、システムの信頼性と拡張性を向上させることができます。
Node.js には、RabbitMQ、Redis、Kafka など、多くのメッセージ キュー実装があります。ここではRabbitMQを例として紹介します。
プロデューサー/コンシューマー パターンは、古典的なメッセージ キュー パターンです。このモードでは、プロデューサーはキューにメッセージを送信する責任を負い、コンシューマーはキューからメッセージを取得して処理する責任を負います。
Node.js では、amqp.node モジュールを使用して RabbitMQ に接続し、キューやスイッチなどの概念を使用してプロデューサー/コンシューマー モデルを実装できます。簡単な例を次に示します。
const amqp = require('amqp'); const connection = amqp.createConnection({ host: 'localhost' }); // 连接RabbitMQ服务器 connection.on('ready', function() { console.log('Connected to RabbitMQ'); // 创建消息队列 connection.queue('hello-queue', { durable: true }, function(queue) { console.log('Created queue: ' + queue.name); // 创建消息生产者 setInterval(function() { const message = 'Hello ' + new Date(); console.log('Sending message: ' + message); connection.publish(queue.name, message, { persistent: true }); }, 1000); // 创建消息消费者 queue.subscribe(function(message) { console.log('Received message: ' + message.data.toString()); }); }); });
上記のコードは、amqp.node モジュールを使用して RabbitMQ サーバーに接続し、プロデューサーとコンシューマーを作成する方法を示しています。プロデューサは 1 秒ごとにメッセージをキューに送信し、コンシューマはキューからメッセージを取得して処理します。
パブリッシュ/サブスクライブ パターンは、もう 1 つの一般的なメッセージ キュー パターンです。このモードでは、メッセージ パブリッシャーと複数のメッセージ サブスクライバーが存在します。パブリッシャはトピックにメッセージを送信し、サブスクライバは独自のサブスクリプション ルールに従ってトピックからメッセージを取得できます。
Node.js では、amqp.node モジュールを使用してパブリッシュ/サブスクライブ モードを実装することもできます。以下は簡単な例です。
const amqp = require('amqp'); const connection = amqp.createConnection({ host: 'localhost' }); // 连接RabbitMQ服务器 connection.on('ready', function() { console.log('Connected to RabbitMQ'); // 创建消息主题 const exchange = connection.exchange('logs', { type: 'fanout' }, function() { console.log('Created exchange: ' + exchange.name); // 创建消息订阅者 connection.queue('', { exclusive: true }, function(queue) { console.log('Created queue: ' + queue.name); queue.bind(exchange, ''); queue.subscribe(function(message) { console.log('Received message: ' + message.data.toString()); }); }); // 创建消息发布者 setInterval(function() { const message = 'Hello ' + new Date(); console.log('Sending message: ' + message); exchange.publish('', message); }, 1000); }); });
上記のコードは、amqp.node モジュールを使用してメッセージ トピック、メッセージ サブスクライバー、およびメッセージ パブリッシャーを作成する方法を示しています。パブリッシャーは 1 秒ごとにトピックにメッセージを送信し、サブスクライバーはトピックからメッセージを取得して処理します。
概要
この記事では、Node.js を使用して分散システムを実装する方法を紹介します。実際のアプリケーションでは、マルチプロセス モードやメッセージ キュー モードの使用など、特定のビジネス ニーズに応じてさまざまな分散通信メカニズムを選択できます。どの方法を選択する場合でも、分散システムの信頼性、拡張性、セキュリティなどの問題に注意を払う必要があります。
以上がNodejs の配布方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。