深入理解NodeJS 多进程和集群

2020-06-17 07:02:20易采站长站整理

stdio
});
}

// 创建子进程
let child = fork("sub_process.js", ["--port", "3000"], {
cwd: path.join(__dirname, "test"),
silent: false
});

// 向子进程发送消息
child.send("hello world");


// 文件:~test/sub_process.js
// 接收主进程发来的消息
process.on("message", data => console.log(data));

// hello world

spawn 中的有一些 fork 没有传的参数(如使用 node 执行文件),都在内部调用 spawn 时传递默认值或将默认参数与 fork 传入的参数进行整合,着重处理了 spawn 没有的参数 silent,其实就是处理成了 spawn 的 stdio 参数两种极端的情况(默认使用 ipc 通信),封装 fork 就是让我们能更方便的创建子进程,可以更少的传参。

execFile 和 exec 实现多进程

execFile 和 exec 是 child_process 模块的两个方法,execFile 是基于 spawn 封装的,而 exec 是基于 execFile 封装的,这两个方法用法大同小异,execFile 可以直接创建子进程进行文件操作,而 exec 可以直接开启子进程执行命令,常见的应用场景如 http-server 以及 weboack-dev-server 等命令行工具在启动本地服务时自动打开浏览器。


// execFile 和 exec
const { execFile, exec } = require("child_process");

let execFileChild = execFile("node", ["--version"], (err, stdout, stderr) => {
if (error) throw error;
console.log(stdout);
console.log(stderr);
});

let execChild = exec("node --version", (err, stdout, stderr) => {
if (err) throw err;
console.log(stdout);
console.log(stderr);
});

exec 与 execFile 的区别在于传参,execFile 第一个参数为文件的可执行路径或命令,第二个参数为命令的参数集合(数组),第三个参数为 options,最后一个参数为回调函数,回调函数的形参为错误、标准输出和错误输出。

exec 在传参上将 execFile 的前两个参数进行了整合,也就是命令与命令参数拼接成字符串作为第一参数,后面的参数都与 execFile 相同。

cluster 集群

开启进程需要消耗内存,所以开启进程的数量要适合,合理运用多进程可以大大提高效率,如 Webpack 对资源进行打包,就开启了多个进程同时进行,大大提高了打包速度,集群也是多进程重要的应用之一,用多个进程同时监听同一个服务,一般开启进程的数量跟 CPU 核数相同为好,此时多个进程监听的服务会根据请求压力分流处理,也可以通过设置每个子进程处理请求的数量来实现 “负载均衡”。

1、使用 ipc 实现集群

ipc 标准进程通信使用 send 方法发送消息时第二个参数支持传入一个服务,必须是 http 服务或者 tcp 服务,子进程通过 message 事件进行接收,回调的参数分别对应发送的参数,即第一个参数为消息,第二个参数为服务,我们就可以在子进程创建服务并对主进程的服务进行监听和操作(listen 除了可以监听端口号也可以监听服务),便实现了集群,代码如下。