最近用node在写一个TCP Socket服务器,但是客户端异常断开后,服务器会报错[Error: read ECONNRESET]错误,然后挂掉,上网查了相关文章,没有好的方法,最好的就是对服务器程序进行进程监控,如果程序退出,监控程序再重新启动服务器程序,进而防止服务器崩掉。下面是实现过程:
网上查了下,有forever和pm2等组件,安装了forever组件,进行了测试,可以正常守护进程,但是每个如果拷贝到其他机器上也需要安装forever组件,如果不能上网就更麻烦,继续寻找其他解决方法…
这次的主角是 child_process.fork(modulePath, [args], [options])
fork函数可以直接运行的node模块,是spawn函数的封装,与spawn函数不同的是,fork之后的子进程与父进程之间会建立IPC管道,用于进程之间的通信,并返回子进程的实例,该实例拥有node进程所有属性与方法。child_process.fork(‘./helloWork.js’); 与 child_process.spawn(‘node’,[‘./helloWork.js’]) 很相似,不同的就是fork建立了IPC管道。
守护进程要做的事儿,就是启动被守护进程,并监听其运行状态,在被守护进程关闭后再次启动,同时,守护进程退出时自动杀掉全部的子进程。
针对以上需求,思路应该是:
->启动守护进程
->依次启动各个子进程,并将返回的object进程实例存下来
->监听子进程的exit事件
->触发子进程exit事件后再次启动子进程
->监听守护进程exit事件,退出时杀死所有子进程
根据该思路,给出我实现的源码:
/**
* Created by zzl on 2017/1/8.
*/
var fork = require('child_process').fork;
//保存被子进程实例数组
var workers = [];
//这里的被子进程理论上可以无限多
var appsPath = ['./app.js'];
var createWorker = function(appPath){
//保存fork返回的进程实例
var worker = fork(appPath);
//监听子进程exit事件
worker.on('exit',function(){
console.log('worker:' + worker.pid + 'exited');
delete workers[worker.pid];
createWorker(appPath);
});
workers[worker.pid] = worker;
console.log('Create worker:' + worker.pid);
};
//启动所有子进程
for (var i = appsPath.length - 1; i >= 0; i--) {
createWorker(appsPath[i]);
}
//父进程退出时杀死所有子进程
process.on('exit',function(){
for(var pid in workers){
workers[pid].kill();
}
});
现在这个只能保证子进程重启,但是父进程如果挂了就完蛋了,所以你可以把上面的代码写成,父进程自己挂了可以重启自己。
[参考文章](https://my.oschina.net/u/1416844/blog/498647)
[参考文章](http://www.yinfan.org/article/nodejs-run-as-daemon)