前言
首先我们来看一个简单的master/worker的例子
// master.js
const http = require("http");
const { fork } = require("child_process");
const server = http.createServer((req, res) => {
const work = fork("./qa/work.js");
work.on("message", m => {
console.log("master 接收到返回结果 :", m);
if (typeof m === "object" && m.type === "fib") {
work.kill();
res.end(m.data.toString());
}
});
work.on("close", (numver, signal) => {
console.log("work 退出", numver, signal);
});
// 子进程收到的内容为 { type: "fib", data: "" }
work.send({ type: "fib", data: 1 });
});
server.listen(3002, () => {
console.log("服务启动成功");
});
worker程序
// worker.js
console.log("子线程已经启动");
function fib(num) {
if (num === 0) return 0;
if (num === 1) return 1;
return fib(num - 2) + fib(num - 1);
}
process.on("message", m => {
console.log("work 接收到参数 :", m);
if (typeof m === "object" && m.type === "fib") {
const result = fib(m.data);
process.send({ type: "fib", data: result });
}
});
process.on("exit", function(code) {
// TODO 这里可以主动释放其他资源 如zookeeper连接等
if (code === 1000) {
console.error("process:uncaughtException");
} else if (code === 1001) {
console.error("process:SIGINT");
} else if (code === 1002) {
console.error("process:SIGTERM");
} else {
console.error("process:unknown");
}
});
process.on("uncaughtException", function(e) {
console.log(e);
// 异常可以选择不退出
process.exit(1000);
});
process.on("SIGINT", function() {
process.exit(1001);
});
process.on("SIGTERM", function() {
process.exit(1002);
});
process.on("SIGHUP", () => {
console.log("接收到退出指令");
});
信号接收
首先无论在子进程还是父进程都可以接收linux的信号SIGINT,SIGTERM,SIGHUP
等。
process.on("SIGINT", function() {
process.exit(1001);
});
process.on("SIGTERM", function() {
process.exit(1002);
});
process.on("SIGHUP", () => {
console.log("接收到退出指令");
});
退出信号
只要是程序能够监听到的退出信号。我们都可以统一通过监听exit
来处理程序
process.on("exit", function(code) {
console.log(code);
});
父进程对子进程的管理
- kill
父进程可以直接kill 子进程,只要拿到子进程的句柄。worker.kill
- 监听子进程关闭信号
worker.on('close', (signal) => {
console.log(signal);
});