nodejs:マルチプロセッサを使う

5426 ワード

nodejsはシングルスレッドであり、Nodeは1つのプロセッサだけで動作するという意味です.しかし、多くのサーバーが複数の核を持っています.幸い、nodejsはclusterモジュールを提供しています.タスクをサブプロセスに割り当てることができます.各サブプロセスには他の子プロセスとのsocket接続などの特殊能力があります.clusterを使用する場合、メインプロセスは各特定のトランザクションに参加しません.メインプロセスはすべてのサブプロセスを管理しますが、サブプロセスとI/O操作が相互作用する場合、直接プロセス操作であり、メインプロセスを通過する必要はありません.
簡単な例:
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if(cluster.isMaster)
{
    //      
    for(var i=0; i)
    {
        cluster.fork();
    }

    cluster.on('death', function(worker)
    {
        console.log('worker' + worker.pid + 'died');
    });    
}
else
{
    //      http  
    http.Server(function(req, res)
    {
        res.writeHead(200);
        res.end("Hello world
"); }).listen(8000); }
clusterの仕事の原理はすべてのNodeプロセスかメインプロセスか、または作業プロセスになります.一つのメインプロセスがcluster.fork()方法を呼び出すと、メインプロセスと同じサブルーチンを作成します.二つのプロセスによって、自分が親/子プロセスの属性であることを確認できます.メインプロセスのcluster.isMasterはtrueに戻りますが、cluster.isWorker()はfalseに戻ります.メインプロセスでは逆です.
socketを共有する以外に、clusterを利用してもっと多くのことをすることができます.プロcessモジュールの場合、このモジュールは一連の属性を提供します.その中で一番効果的なのは、サブルーチンの健康状態を確認することができます.上記の例では、サブルーチンが死亡した時、メインプロセスはconsolone.log()で死亡プロセスを出力します.
cluster.on('death', function(worker)
{
    console.log('worker' + worker.pid + 'died');
    cluster.fork();
});    
この簡単な改良はメインプロセスによって停止せずに死んだプロセスを再起動させ、すべてのCPUが私たちのサーバーで動作していることを保証します.実際にはもっと多くのことができます.作業プロセスはメインプロセスにメッセージを送ることができますので、メモリの使用量など、作業プロセスごとに自分の状態を報告させます.これはメインプロセスがどのような作業プロセスが不安定になっているかを確認し、どの作業プロセスが凍結されていないかを確認することができます.
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

var rssWarn = (12*1024*1024),
    heapWarn = (12*1024*1024);

if(cluster.isMaster)
{
    //      
    for(var i=0; i)
    {
        var worker = cluster.fork();
        worker.on('message', function(m)
        {
            if(m.memory)
            {
                if(m.memory.rss > rssWarn)
                {
                    console.log('Worker' + m.process + 'using too much momory.');
                }
            }
        })
    }

    cluster.on('death', function(worker)
    {
        console.log('worker' + worker.pid + 'died');
        cluster.fork();
    });    
}
else
{
    //      http  
    http.Server(function(req, res)
    {
        res.writeHead(200);
        res.end("Hello world
"); }).listen(8000); // setInterval(function report() { process.send({memory: process.memoryUsage(), process: process.pid}); }) }
この例では、作業プロセスは自分のメモリ使用量を報告しています.子プロセスがメモリを使いすぎると、メインプロセスは警告をログに送ります.これはnodeのメインプロセスをコントロールする能力を持たせて、利益をももたらしました.このメッセージ転送インターフェースは、メインプロセスがメッセージを作業プロセスに返信することも可能である.もちろん、私たちはメッセージでもっと多くのことを伝えられます.