NodeJS进程间通信方法

2019-08-12

NodeJS程序本质上是一个单线程程序,这是Node的最大特点。而Node程序想要规模化拓展,必然涉及到多进程。进程间通讯是组建nodejs服务集群的基础。所以研究进程间通讯是很有必要的。

Linux信号

因为现在几乎Node程序都是部署在Linux上,Linux本身就设计有比较成熟的进程间通讯方法,就是信号。

/* parent.js */
var child = child_process.spawn('node', [ 'child.js' ]);

child.kill('SIGTERM');

/* child.js */
process.on('SIGTERM', function () {
    cleanUp();
    process.exit(0);
});

在上例中,父进程通过.kill方法向子进程发送SIGTERM信号,子进程监听process对象的SIGTERM事件响应信号。不要被.kill方法的名称迷惑了,该方法本质上是用来给进程发送信号的,进程收到信号后具体要做啥,完全取决于信号的种类和进程自身的代码。

IPC

准确的说,Inter-Process Communication也是Linux提供的进程间通讯的一种方式,相比较信号机制,更加的完善。

/* parent.js */
var child = child_process.spawn('node', [ 'child.js' ], {
        stdio: [ 0, 1, 2, 'ipc' ]
    });

child.on('message', function (msg) {
    console.log(msg);
});

child.send({ hello: 'hello' });

/* child.js */
process.on('message', function (msg) {
    msg.hello = msg.hello.toUpperCase();
    process.send(msg);
});

可以看到,父进程在创建子进程时,在options.stdio字段中通过ipc开启了一条IPC通道,之后就可以监听子进程对象的message事件接收来自子进程的消息,并通过.send方法给子进程发送消息。在子进程这边,可以在process对象上监听message事件接收来自父进程的消息,并通过.send方法向父进程发送消息。数据在传递过程中,会先在发送端使用JSON.stringify方法序列化,再在接收端使用JSON.parse方法反序列化。

NodsJS守护进程

守护进程是一种集群服务的常见设计模式。守护进程一般用于监控工作进程的运行状态,在工作进程不正常退出时重启工作进程,保障工作进程不间断运行。

/* daemon.js */
function spawn(mainModule) {
    var worker = child_process.spawn('node', [ mainModule ]);

    worker.on('exit', function (code) {
        if (code !== 0) {
            spawn(mainModule);
        }
    });
}

spawn('worker.js');