最重要的一句话刻在心里:JS是单线程的
总之,是为了“压榨”机器资源。
const fork = require("child_process").fork;
下面 demo 一个创建子进程的例子,该例子先创建一个 server,启动服务之后访问 localhost:3000/get-sum ,页面会打印 sum is 4995500 字符串。
// process.js
const http = require("http");
const fork = require("child_process").fork;
const server = http.createServer((req, res) => {
if (req.url === "/get-sum") {
console.info("主进程 id", process.pid);
// 开启子进程
const computeProcess = fork("./compute.js");
computeProcess.send("开始计算");
// 接收子进程的消息
computeProcess.on("message", data => {
console.info("主进程接收到的信息:", data);
res.end("sum is " + data);
});
// 接收意外情况
computeProcess.on("close", () => {
console.info("子进程因报错而退出");
res.end("error");
})
}
});
server.listen(3000, () => {
console.info("localhost:3000");
});
// compute.js
/**
* @description 子进程,计算
*/
function getSum() {
let sum = 0;
for (let i = 0; i< 10000; i ++) {
sum += i;
}
return sum;
}
// 接收主进程的消息
process.on("message", data => {
console.info("子进程 id", process.pid);
console.info("子进程接收到的信息:", data);
const sum = getSum();
// 发送消息给主进程
process.send(sum);
});
运行 node cluster.js,访问 localhost:3000,页面会打印出 done。
// cluster.js
const http = require("http");
// 根据 cpu 的核数来决定开启进程的数量
const cpuCoreLength = require("os").cpus().length;
const cluster = require("cluster");
// 如果是主进程,就开启子进程
if (cluster.isMaster) {
for (let i = 0; i < cpuCoreLength; i ++) {
cluster.fork(); // 开启子进程
}
cluster.on("exit", worker => {
console.info("子进程退出");
cluster.fork(); // 进程守护,再次开启子进程
});
} else {
// 子进程
// 多个子进程会共享一个 TCP 连接,提供一份网络服务
const server = http.createServer((req, res) => {
res.writeHead(200);
res.end("done");
});
server.listen(3000);
}
但是,实际工作中,我们想要进程守护,会用 pm2 这个包,开启多个进程。