关于node.js的进程管理

若是是单纯的运行一个node进程,那会比较简单,例如:html

node ./example.js

可是通常来讲,当咱们运行一个node进程以后,咱们可能但愿对这个进程进行更多的管理,例如,当node程序是一个server服务时,咱们就有更多的需求。node

例如:git

1.服务挂掉的时候自动重启。github

2.列出全部服务,包括服务的信息。并发

3.可以重启/终止某个服务。dom

4.为服务的运行记录日志。socket

 

1.服务挂掉的时候自动重启。ui

对于这个需求,咱们须要作的是把服务进程当作一个子进程来运行,当子进程不幸挂了,父进程将其重启,例如:this

var spawn = require('child_process').spawn;
var cp = spawn(process.execPath,['./example.js']);

cp.on('exit',function(){
    //restart
});

假设父进程程序名为pro_a,那么经过父进程启动一个子程序会是这样:spa

pro_a ./example.js

传入子程序名,由父程序执行。

 

这样至关于pro_a程序管理子程序的执行:

 

2.列出全部服务,包括服务的信息。

假设咱们执行example.js以后,还有多个程序须要执行,每一个程序都使用pro_a程序来启动:

pro_a ./example.js
pro_a ./server.js
pro_a ./other.js

 

状况变成这样:

 

 

如上图,多个pro_a进程对应开启的多个不一样子程序的进程。

这时候问题来了,咱们但愿知道全部用pro_a启动的子进程的进程信息,要怎么作呢?

例如:

pro_a -l //列出全部子进程信息

 

这时候需求就转变成:新的pro_a进程须要和其余pro_a进程通讯,并获取其余pro_a进程运行的子进程的信息。

 

对于UNIX的跨进程通讯,有几种方式,因为这里不一样进程在同一个机器中,所以咱们这里采用UNIX domain socket的方式(不用通过网卡),让在不一样pro_a进程间进行通讯。

使用这种方式,咱们须要作的是pro_a进程每次建立子进程的时候,启用一个server,并监听对应的sock文件,那么小心的pro_a进程启动以后,就能够经过遍历全部sock文件并对有效sock文件进行链接,从而可以和不一样pro_a进程之间进行消息的通讯。

 

例如:

建立子进程的pro_a:

var net = require('net');    
//使用UNIX domain socket
var server = net.createServer(function(socket){    
    socket.setEncoding('UTF8');
    socket.on('data',function(){
        //收到消息后,向请求方发送子进程相关信息
        socket.write(JSON.stringify({
            pid:child_process.pid
            //...
        }));
    });

});

server.listen(socketPath + 'resume_' + Date.now() + '.sock');       

 

这样每一个pro_a进程建立子进程以后,都会对应产生一个sock文件:

 

 

对于新的pro_a进程,第一步是获取全部sock文件,并进行链接:

var getAllSocketFiles = function(){
    var socketFiles;
    try{
        socketFiles = fs.readdirSync(socketPath);
    }
    catch(ex){
        if(ex.code == 'ENOENT'){
            fs.mkdirSync(socketPath);
        }

        socketFiles = fs.readdirSync(socketPath);
    }
    return socketFiles;
};

 

针对每一个sock文件,建立socket进行链接,并发送消息请求:

var socket = new net.Socket();
socket.setEncoding('UTF8');

socket.connect(this.socketName,function(){
    socket.write(JSON.stringify({
        //请求对应的子进程信息
    }))
});

socket.on('data',function(){
    data = JSON.parse(data);
    //得到对应子进程信息
});

 

 

这样pro_a进程就能从其余pro_进程中获取到信息。

 

3.可以重启/终止某个服务。

因为咱们设置了子程序在挂掉后会自动重启,所以咱们须要增长一个命令让程序在须要时能正常关闭,例如:

pro_a -s 1140 //强制终止掉进程号为1140的子进程

 

此时该pro_a进程须要链接全部其余pro_a进程并获取他们的子进程信息(就像上面-l那样),而后筛选出pid未1140的子进程,再次经过socket发送关闭指令,对应的server接收到关闭指令后把其子进程kill掉。

 

4.为服务的运行记录日志。

这个只须要pro_a监听子进程的事件,并实时写入log文件就ok了。而且咱们能够经过命令让心的pro_a进程可以查看某个其余pro_a进程中子进程的log,例如:

pro_a -L 1130 // 查看1130的子进程的log

 

原理和3类似,获取全部pro_a进程信息,筛选出pid为1130的子进程,socket发送获取log的指令,对应server把log信息返回。

 

我把以上pro_a的功能以及更多其余功能封装成一个叫Resume.js的程序放倒github上,有兴趣的同窗能够看看:

https://github.com/csonlai/Resume.js

 

其中包含了上面功能的实现源码。咱们能够经过Resume.js进行简单的node进程管理。

 

欢迎围观,转载请标明出处:

http://www.cnblogs.com/Cson/p/4069868.html 

相关文章
相关标签/搜索