保持运行
根据 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 kill
、pm2 stop
、pm2 reload
pm2 结束进程的流程:首先向进程发送 SIGINT 信号,开发者可以监听进程上的 SIGINT 事件来主动退出进程。
js
process.on('SIGINT', ()=>{
// 清理资源等
process.exit()
})
如果一定时间(默认1.6秒,可配置)后进程没有主动结束,pm2 将向进程发送 SIGKILL 信号,强制结束进程。