我自己的写法是创建一个主进程master.js
,带子进程worker.js
,但是现在遇到一个问题就是,子进程遇到错误崩溃时会让主进程直接崩溃,原因是worker.js
中的process.send({act: 'suicide'});
行报错,错误代码:
TypeError: process.send is not a function
下方是源码:
//master.js
var express = require('express');
var port = process.env.PORT || 18080;
var app = express();
app.listen(port);
var fork = require('child_process').fork;
var cpus = require('os').cpus();
var workers = {};
var createWorker = function () {
var worker = fork('./worker.js');
// 退出时重新启动新的进程
worker.on('exit', function () {
console.log('Worker ' + worker.pid + ' exited.');
delete workers[worker.pid];
createWorker();
});
// 句柄转发
worker.send('server', express);
workers[worker.pid] = worker;
console.log('Create worker. pid: ' + worker.pid);
};
for (var i = 0; i < cpus.length; i++) {
createWorker();
}
// 进程自己退出时,让所有工作进程退出
process.on('exit', function () {
for (var pid in workers) {
workers[pid].kill();
}
});
//worker.js
var worker;
process.on('message', function (m, tcp) {
if (m === 'express') {
worker = tcp;
worker.on('connection', function (socket) {
express.emit('connection', socket);
});
}
});
process.on('uncaughtException', function (err) {
process.send({act: 'suicide'});
// 停止接收新的连接
worker.close(function () {
// 所有已有连接断开后,退出进程
process.exit(1);
});
// 5秒后退出进程
setTimeout(function () {
process.exit(1);
}, 5000);
});
var createWorker = function () {
var worker = fork(__dirname + '/worker.js');
// 启动新的进程
worker.on('message', function (message) {
if (message.act === 'suicide') {
createWorker();
}
});
worker.on('exit', function () {
console.log('Worker ' + worker.pid + ' exited.');
delete workers[worker.pid];
});
worker.send('server', express);
workers[worker.pid] = worker;
console.log('Create worker. pid: ' + worker.pid);
};
迷茫2017-04-17 13:45:42
I have found a method here. Thanks to borgchen for the instructions. The solution is:
// app.js
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' restart');
setTimeout(function() {cluster.fork();},2000);
});
} else {
// 这里放入口文件的东西并且直接使用express监听端口
var express = require('express');
var port = process.env.PORT || 18080;
var app = express();
app.listen(port);
}
There is no need to runmaster.js
with worker.js
, just runapp.js