JavaScript群集工作程序未接收消息

时间:2017-10-27 13:26:44

标签: node.js process cluster-computing

我在Windows上有一个NodeJS(版本4.4.3)应用程序,它作为服务器运行并分叉子进程执行一些数据处理。由于它必须处理的数据量可能无法响应。我想杀死这个任务,但不知道如何确定这个任务是否已完成或是否挂起。我正在使用基于群集的进程管理,如下所示。我希望它拥有管理信号处理的所有部分。

在实际应用程序中,子进程没有收到关闭消息,我看不到它们的退出消息。

感谢您的帮助。

感谢。

var cluster = require('cluster');
clients = 0,  // tracks number of active clients    
    workers = 1;  // configuration for number of worker tasks




/*
 * Code to perform cluster process management.
 */ 
if (cluster.isMaster)
{
  // create the workers.
  // Use env variables to dictate client or worker
  for (var i = 0; i < workers; i++)
  {
    cluster.fork({ "TYPE": 'worker'});
  }


  // Log that worker process has started
  cluster.on('online', function(worker) 
  {
    console.log('Worker ' + worker.process.pid + ' is online.');
  });


  // Detect the death of a worker and log it
  var deadWorkers = 0; // tracks dead worker tasks
  cluster.on('death', function(worker)
  {
    deadWorkers++;
    console.log('worker ' + worker.pid + ' died.');

    console.log('worker ' + worker.process.pid + ' died.');

    if (deadWorkers === workers) 
    {
      console.log('Server is exiting as all workers are dead.')
      process.exit(0)
    }      
  });

  // Keep a track of clients connecting and disconnecting
  var deadClients = 0; // tracks number of dead clients   
  cluster.on('disconnect', function(worker)
  {
    deadClients++;
      console.log('worker ' + worker.pid + ' disconnected.');   
    console.log('number of dead clients: ' + clients);

    console.log('worker ' + worker.process.pid + ' disconnected.');

    if (deadClients === clients) 
    {
      console.log('Server is exiting as all clients are dead.')
      process.exit(0)
    }
  });


  cluster.on('connect', function(worker)
  {
    clients++;
    console.log('number of clients: ' + clients);
  });


  cluster.on('exit', (worker, code, signal) =>
  {
    deadWorkers++;

      console.log('worker ' + worker.process.pid + ' exited with signal: ' + signal);

    if (deadWorkers === workers) 
    {
      console.log('Server is exiting as all clients are dead.')
      process.exit(0)
    }
  });


  // start the server task
  try
  {
    serverTask();
  }
  catch(err)
  {
    console.log("caught exception launching server task: " + err);
  }

}
else
{
  try
  {
    workerTask();
  }
  catch(err)
  {
    console.log("caught exception launching worker task when cluster is not a master: " + err);
  }

  if (cluster.isWorker)
  {  
    process.on('message', (msg) => 
    {
      console.log('worker received: ' + msg);

      if ('shutdown' === msg) 
      {
        var pid = process.pid;
        console.log('Worker ' + pid + ' is exiting...');
        process.disconnect();
        process.exit(0);
      }
    });
  }
}



function serverTask()
{
  console.log("server task")
}



function workerTask()
{
  console.log("worker task")
}


process.on('SIGINT', function() 
{  
  handleSignal('SIGINT');
});



function handleSignal(signal) 
{

  if(cluster.isMaster)
  {
      console.log("terminating due to signal: " + signal);

    for (var i in cluster.workers) 
    {
      console.log('killing workers ');
      cluster.workers[i].send('shutdown');
      cluster.workers[i].disconnect();
      timeout = setTimeout(() => { cluster.workers[i].kill(); }, 2000);
    }
    process.exit(signal);
  }  
}

1 个答案:

答案 0 :(得分:0)

  1. 将ES6代码与Node一起使用时,至少使用Node v6.x(或更高版本)非常重要。这是因为ES6支持在该版本之下并不是很好 - 这里有一个最新的参考:http://node.green
  2. 下面的工作代码示例以及一些其他建议(我建议省略一些冗余事件)。
  3. 我还建议使用带有良好linter(如WebStorm或VS Code)的JS for IDE - 代码中存在一些语法问题(如顶部的var decl)。

    var cluster = require('cluster'),
        clients = 0,  // tracks number of active clients
        workers = 3;  // configuration for number of worker tasks
    
    /*
     * Code to perform cluster process management.
     */
    if (cluster.isMaster) {
        // create the workers.
        // Use env variables to dictate client or worker
        for (var i = 0; i < workers; i++) {
            cluster.fork({"TYPE": 'worker'});
        }
    
        // Log that worker process has started
        cluster.on('online', function (worker) {
            clients++;
            console.log('Worker ' + worker.process.pid + ' is online.');
            console.log('number of clients: ' + clients);
        });
    
    
        // TODO This doesn't seem to be an event anymore...outdated doc reference?
        /*// Detect the death of a worker and log it
        var deadWorkers = 0; // tracks dead worker tasks
        cluster.on('death', function (worker) {
            deadWorkers++;
            console.log('worker ' + worker.pid + ' died.');
    
            console.log('worker ' + worker.process.pid + ' died.');
    
            if (deadWorkers === workers) {
                console.log('Server is exiting as all workers are dead.');
                process.exit(0)
            }
        });*/
    
        // Keep a track of clients connecting and disconnecting
        var deadClients = 0; // tracks number of dead clients
        cluster.on('disconnect', function (worker) {
            deadClients++;
            console.log('worker ' + worker.pid + ' disconnected.');
            console.log('number of dead clients: ' + clients);
    
            console.log('worker ' + worker.process.pid + ' disconnected.');
    
            // TODO It might be worth actually spawning a new child to keep the process alive
            // rather than just existing because all clients are dead.
            if (deadClients === clients) {
                console.log('Server is exiting as all clients are dead.');
                process.exit(0);
            }
        });
    
        // TODO Not necessary and out-of-date possibly - replaced by the online event above
        /*cluster.on('connect', function(worker)
        {
            clients++;
            console.log('number of clients: ' + clients);
        });*/
    
        cluster.on('exit', function(worker, code, signal) {
            deadWorkers++;
    
            console.log('worker ' + worker.process.pid + ' exited with signal: ' + signal);
    
            if (deadWorkers === workers) {
                console.log('Server is exiting as all clients are dead.');
                process.exit(0)
            }
        });
    
        // start the server task
        try {
            serverTask();
        }
        catch (err) {
            console.log("caught exception launching server task: " + err);
        }
    } else {
        try {
            workerTask();
        }
        catch (err) {
            console.log("caught exception launching worker task when cluster is not a master: " + err);
        }
    
        if (cluster.isWorker) {
            process.on('message', function(msg)
            {
                console.log('worker received: ' + msg);
    
                if ('shutdown' === msg) {
                    var pid = process.pid;
                    console.log('Worker ' + pid + ' is exiting...');
    
                    // TODO again, this is un-necessary
                    // process.disconnect();
    
                    process.exit(0);
                }
            });
        }
    }
    
    function serverTask() {
        console.log("server task")
    }
    
    
    function workerTask() {
        console.log("worker task")
    }
    
    
    process.on('SIGINT', function () {
        handleSignal('SIGINT');
    });
    
    
    function handleSignal(signal) {
    
        if (cluster.isMaster) {
            console.log("terminating due to signal: " + signal);
            console.log('Killing all workers');
    
            for (var i in cluster.workers) {
                cluster.workers[i].send('shutdown');
    
                // TODO There is no need to disconnect workers manually
                //cluster.workers[i].disconnect();
    
                setTimeout(function() {
                    cluster.workers[i].kill();
                }, 2000);
            }
    
            process.exit(signal);
        }
    }