Nodejsを使用する友人はすべて、ノードがシングルスレッドであることを知っています。つまり、8コアCPUで実行する場合、1つのコアのコンピューティングパワーしか使用できません。
単一のスレッドは常にノードに対する批判でしたが、バージョン0.6にクラスターの導入により、この状況は変わりました。開発者はクラスターに依存して、ノードサーバーをマルチスレッドサーバーに簡単に拡張できます。
クラスターとは何ですか
クラスターは、ノードが提供するマルチスレッドライブラリです。ユーザーはそれを使用して複数のスレッドを作成できます。スレッドはリスニングポートを共有します。このポートに外部リクエストがある場合、クラスターはリクエストをランダムスレッドに転送します。各ノードスレッドは数十メガバイトのメモリを占有するため、PHPのような各リクエストのスレッドを作成することは不可能です。一般的に、作成されたスレッドの数は、せいぜいCPUコアの数を超えません。
コードコピーは次のとおりです。
var cluster = require( 'cluster');
var http = require( 'http');
var numcpus = require( 'os')。cpus()。length;
if(cluster.ismaster){
//フォークワーカー。
for(var i = 0; i <numcpus; i ++){
cluster.fork();
}
cluster.on( 'exit'、function(worker、code、signal){
console.log( 'worker' + worker.process.pid + 'die');
});
} それ以外 {
//ワーカーはTCP接続を共有できます
//この場合、HTTPサーバー
http.createserver(function(req、res){
Res.Writehead(200);
res.End( "Hello World/n");
})。聞きます(8000);
}
上記のコードに示すように、Cluster.ismasterはプログラムが実行されているときにTRUEに設定されます。 cluster.fork()を呼び出した後、プログラムはスレッドを作成して再実行します。この時点で、cluster.ismasterはfalseに設定されます。主にこの変数を使用して、現在のスレッドがチャイルドスレッドに属しているかどうかを判断します。
また、各チャイルドスレッドが作成された後、競合を引き起こすことなくポート8000に耳を傾けることにも注意してください。これは、クラスター共有ポートの関数です。
スレッド間の通信
スレッドが作成されると、メモリやデータを互いに共有しません。すべてのデータ交換は、worker.sendとworker.on( 'message'、ハンドラー)を介してメインスレッドでのみ処理できます。以下には、ブロードキャストシステムの例がリストされています。
コードコピーは次のとおりです。
var cluster = require( 'cluster');
var http = require( 'http');
var numcpus = require( 'os')。cpus()。length;
if(cluster.ismaster){
var Workers = [];
//新しいワーカーを作成します
function newWorker(){
var Worker = cluster.fork();
//情報を聞いてください。タイプが放送されている場合、ブロードキャストとして決定されます
worker.on( 'message'、function(msg){
if(msg.type == 'broadcast'){
var event = msg.event;
//この放送をすべての労働者に送信します
workers.foreach(function(worker){
worker.send(event);
})
}
});
帰還労働者。
}
for(var i = 0; i <numcpus; i ++){
workers.push(newworker());
}
cluster.on( 'online'、function(worker){
console.log( 'Worker%dはオンライン'、worker.id);
})
} それ以外 {
var Worker = cluster.worker;
//ブロードキャストは、タイプブロードキャストでメッセージを送信することです。イベントはブロードキャストコンテンツです
worker.broadcast = function(event){
worker.send({
タイプ:「ブロードキャスト」、
イベント:イベント
});
}
//これは、ここでworker.を使用して返された情報を聞くことができません。
process.on( 'message'、function(event){
console.log( 'worker:'+worker.id+''+event.workeridから回復したイベント);
})
//ブロードキャストを送信します
worker.broadcast({
メッセージ:「オンライン」、
workerid:worker.id
})
}
注意すべき問題
また、データはスレッド間で共有できず、すべてのデータ交換はスレッド間の通信を通じてのみ交換できることも上記で言及しています。さらに、交換されたデータはシリアル化可能であるため、関数、ファイル記述子、およびHTTPResponseに合格することはできません。
クラスターを使用する場合は、プログラムを設計する際にデータ交換の問題を考慮する必要があります。私自身のアプローチは、Redisのセッションと同様のすべてのデータを保存することであり、各スレッドはストレージと引き出し作業を行い、すべてのデータはノードメモリに配置されません。
最後のポイントでは、クラスターは現在、ノードによって実験として正式にマークされており、APIは将来変化する可能性があります。