【Node】Node中如何守护进程

2023/02/08 10:42:14

捕获抛到全局的异常

NodeJS 环境中如果出现了未捕获的异常会导致进程崩溃,可以用 process 的 uncaughtException 事件来捕获这些异常:

process.on("uncaughtException", (e) => {
  console.error("process error is:", e.message);
});

然后在事件处理程序中重启应用:

process.on("uncaughtException", (e) => {
  console.error("process error is:", e.message);
  restartServer(); // 重启服务
});

这种处理方式可能会导致内存泄漏:当异常出现时,直接从对应执行栈中断,而到 process 捕获的异常事件下,导致了 v8 引擎的垃圾回收功能不能按照正常流程工作,然后开始出现内存泄漏问题。

利用 domain 模块来守护进程

使用 domain 模块也能达到同样的效果,但是同样会出现内存泄漏的问题。

import domain from "domain";
const d = domain.create();
const dot = 3;
let count = 0;
function task() {
  console.log(count++, dot);
  if (count === dot) {
    throw new Error();
  }
  setTimeout(task, 1000);
}

d.on("error", (error) => {
  console.log("err", error);
  d.run(task);
});

d.run(task);

多进程模式加异常捕获后重启

以多进程模式去部署应用,当某一个进程触发全局异常捕获后,重启该进程释放内存,此时其他进程可以继续提供服务。

const cluster = require("cluster");
const os = require("os");
const http = require("http");
const domain = require("domain");

const d = domain.create();

if (cluster.isMaster) {
  const cpuNum = os.cpus().length;
  for (let i = 0; i < cpuNum; ++i) {
    cluster.fork();
  }
  // fork work log
  cluster.on("fork", (worker) => {
    console.info(`${new Date()} worker${worker.process.pid}进程启动成功`);
  });
  // 监听异常退出进程,并重新fork
  cluster.on("exit", (worker, code, signal) => {
    console.info(`${new Date()} worker${worker.process.pid}进程启动异常退出`);
    cluster.fork();
  });
} else {
  http
    .createServer((req, res) => {
      d.add(res);
      d.on("error", (err) => {
        console.log("记录的err信息", err.message);
        console.log("出错的 work id:", process.pid);
        // uploadError(err)  // 上报错误信息至监控
        res.end("服务器异常, 请稍后再试");
        // 将异常子进程杀死
        cluster.worker.kill(process.pid);
      });
      d.run(handle.bind(null, req, res));
    })
    .listen(8080);
}

function handle(req, res) {
  if (process.pid % 2 === 0) {
    throw new Error(`出错了`);
  }
  res.end(`response by worker: ${process.pid}`);
}

参考

nodejs 中的异常错误处理open in new window