簡単なNodeJS実現のプロセス間通信の例を書きました.
8228 ワード
1.clusterの紹介
皆さんはnodejsが単一プロセスの単一スレッドのサーバーエンジンであることを知っています.どんなに強力なハードウェアがあっても、単一CPUで計算するしかないです.そこで、第三者のclusterを開発し、nodeがマルチコアCPUを利用して並行して実現できるようにしました.nodejsの発展に従って、nodejsに環境を生産させて、多プロセスの多核処理を支持しなければなりません.V 0.0.6バージョンでは、Nodejsにclusterの特性が内蔵されています.これにより、Nodejsはついに独立したアプリケーション開発ソリューションとして目に映るようになりました.
clusterはnodejs内蔵のモジュールで、nodejs多核処理に用いられます.clusterモジュールは、多プロセス並列化プログラムの開発難易度を簡略化し、負荷バランスのためのクラスタを容易に構築することができます.
2.clusterの動作原理
各ワーカープロセスはchild_を使うことによってprocess.fork関数は、IPC(Inter-Parocess Communication、プロセス間通信)に基づいて、masterプロセスとの間の通信を実現します.
workerがserver.listen(...)関数を使用するとパラメータシーケンスをmasterプロセスに伝えます.マスタープロセスがworkersにマッチしたら、最後の文を労働者に伝えます.マスターがワーカーにマッチしていない場合は、ワーカーを作成して、文を伝えてワーカーに伝えます.
境界条件では、3つの面白い行動があります.注:下のserver.listenは、下の「http.Server-」net.Server類への呼び出しです. 1.server.listen({fd:7}:masterとworkerの通信過程で、ファイルを転送することによって、masterは「ファイル記述は7」であって、「ファイル記述は7」の参照を転送するのではなく、「ファイル記述は7」を傍受します. .server.listen(handle):masterとworkerの通信プロセスは、handle関数を介して通信し、プロセス連絡なしに に通信する..server.listen(0):masterとworkerの通信プロセスでは、クラスタ内のworkerはランダムポートを開いて共有し、socket通信によって、上記の例の57132 のように通信する.
複数のプロセスが同じリソースにある場合、オペレーティングシステムの負荷バランスは非常に効率的である.Node.jsにはルーティングロジックがありません.worker間に共有状態がありません.したがって、プログラムはメモリベースのsessionなど、簡単に設計する必要があります.
ワーカーは独力で運行していますので、プログラムの必要に応じて独立して削除または再起動できます.ワーカーは互いに影響しません.ウォーカーが生きている限り、マスタは接続を受信し続けます.Nodeは自動的にworkersの数を維持しません.私たちは自分の接続池を作ることができます.
3.clusterのAPI
公式サイトのアドレス:http://nodejs.org/api/cluster.html#cluster_cluster
clusterオブジェクトの各種属性と関数 cluster.settings:クラスタパラメータオブジェクト を構成する. cluster.isMaster:マスターノード ではないかと判断する. cluster.isWorker:ワーカーノード であるかどうかを判定する. Event:'fork':workプロセス作成イベントを傍受する Event:'online':ウォーカーを待ち受けて成功イベントを作成しました. Event:'listening':モニターワーカーがmaster状態イベント に向かう. Event:'disconnect':ウォーカー切断イベントを傍受する Event:'exit':worker退出イベントを傍受する Event:'setup':setupMasterイベントを傍受する cluster.setupMaster(settings):クラスタパラメータを設定する cluster.fork(env):workプロセス を作成する. cluster.disconnect(calback):worketプロセスを閉じる cluster.worker:現在のworkerオブジェクト を取得する. cluster.workers:クラスタ内で生存している全てのウォーカーオブジェクト を取得する.
workerオブジェクトの各種属性と関数:cluster.workersを通じて、cluster.worketが得られます. worker.id:プロセスID番号 worker.process:ChildProcessオブジェクト worker.suicide:disconnect()後、workerが自殺したかどうかを判断する worker.send:masterはworkerにメッセージを送ります.注:workerがmasterにメッセージを送るにはprocess.send を使います. worker.kill([signal='SIGTRM]):指定されたウォーカーを殺し、別名destory() worker.disconnect():workカーを切断し、workerを自殺させます. Event:'message':マスターとウォーカーのメッセージイベントを傍受する Event:'online':指定されたウォーカーを傍受して成功イベントを作成する Event:'listening':マスター・ウォーカー状態イベントを傍受する Event:'disconnect':ウォーカー切断イベントを傍受する Event:'exit':worker退出イベントを傍受する 4.マスターとワーカーの通信例
皆さんはnodejsが単一プロセスの単一スレッドのサーバーエンジンであることを知っています.どんなに強力なハードウェアがあっても、単一CPUで計算するしかないです.そこで、第三者のclusterを開発し、nodeがマルチコアCPUを利用して並行して実現できるようにしました.nodejsの発展に従って、nodejsに環境を生産させて、多プロセスの多核処理を支持しなければなりません.V 0.0.6バージョンでは、Nodejsにclusterの特性が内蔵されています.これにより、Nodejsはついに独立したアプリケーション開発ソリューションとして目に映るようになりました.
clusterはnodejs内蔵のモジュールで、nodejs多核処理に用いられます.clusterモジュールは、多プロセス並列化プログラムの開発難易度を簡略化し、負荷バランスのためのクラスタを容易に構築することができます.
2.clusterの動作原理
各ワーカープロセスはchild_を使うことによってprocess.fork関数は、IPC(Inter-Parocess Communication、プロセス間通信)に基づいて、masterプロセスとの間の通信を実現します.
workerがserver.listen(...)関数を使用するとパラメータシーケンスをmasterプロセスに伝えます.マスタープロセスがworkersにマッチしたら、最後の文を労働者に伝えます.マスターがワーカーにマッチしていない場合は、ワーカーを作成して、文を伝えてワーカーに伝えます.
境界条件では、3つの面白い行動があります.注:下のserver.listenは、下の「http.Server-」net.Server類への呼び出しです.
複数のプロセスが同じリソースにある場合、オペレーティングシステムの負荷バランスは非常に効率的である.Node.jsにはルーティングロジックがありません.worker間に共有状態がありません.したがって、プログラムはメモリベースのsessionなど、簡単に設計する必要があります.
ワーカーは独力で運行していますので、プログラムの必要に応じて独立して削除または再起動できます.ワーカーは互いに影響しません.ウォーカーが生きている限り、マスタは接続を受信し続けます.Nodeは自動的にworkersの数を維持しません.私たちは自分の接続池を作ることができます.
3.clusterのAPI
公式サイトのアドレス:http://nodejs.org/api/cluster.html#cluster_cluster
clusterオブジェクトの各種属性と関数
workerオブジェクトの各種属性と関数:cluster.workersを通じて、cluster.worketが得られます.
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log('[master] ' + "master started, pid:" + process.pid);
cluster.on('fork', function (worker) {
console.log('[master] ' + 'fork: worker' + worker.id);
});
cluster.on('online', function (worker) {
console.log('[master] ' + 'online: worker' + worker.id);
});
cluster.on('listening', function (worker, address) {
console.log('[master] ' + 'listening: worker' + worker.id + ',pid:' + worker.process.pid + ', address:' + address.address + ":" + address.port);
});
cluster.on('disconnect', function (worker) {
console.log('[master] ' + 'disconnect: worker' + worker.id);
});
cluster.on('exit', function (worker, code, signal) {
console.log('[master] ' + 'exit worker' + worker.id + ' died, try to fork a new worker.');
cluster.fork();
});
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
Object.keys(cluster.workers).forEach(function (id) {
cluster.workers[id].on('message', function (msg) {
console.log('[master] ' + 'received msg:' + msg + 'from worker' + id);
});
});
function eachWorker(callback) {
for (var id in cluster.workers) {
callback(cluster.workers[id]);
}
}
var i = 0;
setTimeout(function () {
eachWorker(function (worker) {
i++;
worker.send('[master] ' + 'send msg ' + i + ' to worker' + worker.id);
});
}, 3000);
} else if (cluster.isWorker) {
console.log('[worker] ' + "worker" + cluster.worker.id + " started, pid:" + process.pid);
process.on('message', function (msg) {
console.log('[worker] worker' + cluster.worker.id + ' received msg:' + msg);
process.send('[worker] send msg ' + cluster.worker.id + ' to master.');
});
http.createServer(function (req, res) {
var response = 'worker received request, id:' + cluster.worker.id + ',pid:' + process.pid;
console.log(response);
res.writeHead(200, { "content-type": "text/html" });
res.end(response);
}).listen(5000);
}