我在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);
}
}
答案 0 :(得分:0)
我还建议使用带有良好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);
}
}