Skip to content
导航

保持运行

根据 uncaughtException - 正确处理未捕获的错误 一节,当未捕获的错误发生时,正确的做法是:记录日志,清理资源如运行时产生的文件,主动退出进程。如需重启,则通过外部监视器来重启进程。

本文介绍最流行的外部监视器pm2,负责重启进程。

以一个简单的 http 服务应用为例

js
// app.js
require('http').createServer((req, res)=>{}).listen(8080, ()=> console.log('listening on port 8080'))
// 服务启动 5s 后发出未捕获的错误,结束运行
setTimeout(()=>{
    throw new Error('error')
}, 5000)

pm2

pm2 是一个守护进程管理器,用法简单。

shell
# npm install -g pm2
pm2 start app.js

运行后 pm2 会在后台启动 app.js。

当 app.js 运行结束时,pm2 会自动重启 app.js。

查看 pm2 后台运行的进程:

shell
pm2 ls
# or
pm2 list

将在控制台打印:

shell
┌────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
 id  name    namespace    version  mode     pid       uptime       status     cpu       mem       user      watching 
├────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
 0   app     default      N/A      fork     7788      0s      1     online     0%        42.4mb    username      disabled 
└────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘

为了结束这个循环,可以直接运行 pm2 kill,结束所有 pm2 进程及守护进程,也可以用 pm2 stop all 停止所有 pm2 启动的进程,还可以单独停止进程

shell
pm2 stop 0
# or
pm2 stop app

pm2 启动的进程运行中输出的日志,可以通过 pm2 logs 查看实时日志

pm2 logs # 默认同时查看 pm2 启动的所有进程日志
pm2 logs 0 # 仅查看 id=0 的进程日志
pm2 logs app # 仅查看 name=app 的进程日志

pm2 还提供 pm2 monit 命令启动CLI仪表盘,方便查看实时日志。

pm2 的日志是写入文件的,要看历史日志可以直接查看日志文件,日志文件路径在查看实时日志时会打印出来。

处理进程退出

pm2 killpm2 stoppm2 reload

pm2 结束进程的流程:首先向进程发送 SIGINT 信号,开发者可以监听进程上的 SIGINT 事件来主动退出进程。

js
process.on('SIGINT', ()=>{
  // 清理资源等
  process.exit()
})

如果一定时间(默认1.6秒,可配置)后进程没有主动结束,pm2 将向进程发送 SIGKILL 信号,强制结束进程。

参考资料