pm2是Node.js下的生产环境进程管理工具,就是我们常说的进程守护工具。 可以用来在生产环境中进行自动重启、日志记录、错误预警等等。

在我们开始之前,首先使用npm安装pm2

npm install -g pm2 

PM2文档:https://github.com/Unitech/pm2

单线程JavaScrip的脆弱性

传统Web服务器会为每一个HTTP请求创建线程,因而线程发生异常不会影响到整个服务器进程。 然而JavaScript天生是单线程的,任何未捕获异常都会造成进程异常退出。 这也是我们需要pm2的关键原因,例如下面这个简单的Node.js应用:

// file: index.js
const http = require('http');

const server = http.createServer((req, res) => {
    if(req.url === '/error'){
        throw 'Intended Error';
    }
    res.end('Hello world');
});

server.listen('3000', 'localhost', () => {
    console.log(`Server running at http://localhost:3000/`);
});

当我们访问http://loacalhost:3000/error时,进程便会异常退出:

  pm2 node index.js
Server running at http://localhost:3000/

/private/tmp/pm2/index.js:5
        throw 'Intended Error';
        ^
Intended Error

pm2基本使用

pm2最基本的功能就是自动重启Node.js应用,至少可以让Node.js更稳定地运行。

➜  pm2 pm2 start index.js --name www
[PM2] Starting index.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
│ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
│ www      │ 0  │ fork │ 57372 │ online │ 0       │ 0s     │ 14.480 MB   │ disabled │
└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘

--name参数用来指定App name,这个App name可以通过pm2 delete www来删除。

启动后pm2给出了当前所有应用的状态表。 使用pm2 list命令可以随时查看上述表格。然后我们试着再次访问http://localhost:3000/error, 然后查看pm2日志:

➜  pm2 pm2 logs www
[PM2] Tailing last 20 lines for [www] process
www (out): Server running at http://localhost:3000/
[PM2] Streaming realtime logs for [www] process
www Intended Error
www Server running at http://localhost:3000/

可以看到在Intended Error之后index.js被立即重启, 输出Server running at http://localhost:3000/。 可以访问http://localhost:3000来验证服务器还活着。

日志管理

上一节中看到pm2 logs xxx可以查xxx(对应App name)的日志。 除此之外,我们还可以给日志输出添加时间戳:

➜  pm2 logs --timestamp "HH:mm:ss" www
12:31:53 www Intended Error
12:31:53 www Server running at http://localhost:3000/

在系统管理中常常会碰到巨大无比的日志文件,其实我们可以清除太久以前的日志。 pm2还提供了一个模块管理系统,通过它可以安装日志轮替模块

日志存储的默认地址是~/.pm2/logs/<app-name>-out-<number>.log(标准输出) 和~/.pm2/logs/<app-name>-error<number>.log(错误输出)。

pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 1K                   # (1KB)
pm2 set pm2-logrotate:compress true                 # (compress logs when rotated)
pm2 set pm2-logrotate:rotateInterval '*/1 * * * *'  # (force rotate every minute)

参考文档:http://pm2.keymetrics.io/docs/usage/log-management/

性能监视

pm2也可以实时监测性能参数:

➜  pm2 monit
⌬ PM2 monitoring (To go further check out https://app.keymetrics.io)

 ● www                                 [                              ] 0 %
[0] [fork_mode]                        [||||                          ] 26.379 MB

也可以查看某个App的详细信息:

➜  pm2 pm2 describe www
Describing process with id 0 - name www
┌───────────────────┬──────────────────────────────────────────┐
│ status            │ online                                   │
│ name              │ www                                      │
│ id                │ 0                                        │
│ path              │ /private/tmp/pm2/index.js                │
│ args              │                                          │
│ exec cwd          │ /private/tmp/pm2                         │
│ error log path    │ /Users/harttle/.pm2/logs/www-error-0.log │
│ out log path      │ /Users/harttle/.pm2/logs/www-out-0.log   │
│ pid path          │ /Users/harttle/.pm2/pids/www-0.pid       │
│ mode              │ fork_mode                                │
│ node v8 arguments │                                          │
│ watch & reload    │ ✘                                        │
│ interpreter       │ node                                     │
│ restarts          │ 3                                        │
│ unstable restarts │ 0                                        │
│ uptime            │ 11m                                      │
│ created at        │ 2016-09-01T04:24:57.324Z                 │
└───────────────────┴──────────────────────────────────────────┘
Process configuration

Probes value
┌────────────┬────────┐
│ Loop delay │ 0.63ms │
└────────────┴────────┘

发送邮件

pm2本身不提供邮件通知支持。可以使用https://github.com/harttle/pm2-notify来监听pm2事件。 安装方式:

git clone https://github.com/harttle/pm2-notify
cd pm2-notify && npm install
# 复制一份配置文件,你的配置在config.yml中
cp config.example.yml config.yml
# 复制一份邮件模板
cp template.example.md template.md
# 启动
node index.js

当任何一个pm2进程状态发生变化时,都会发送邮件。 pm2-notify使用nodemailer发送邮件, 所以config.yml中的SMTP等邮件相关配置都请参照nodemailer文档。

本文采用 知识共享署名 4.0 国际许可协议(CC-BY 4.0)进行许可,转载注明来源即可: https://harttle.land/2016/09/07/pm2-express.html。如有疏漏、谬误、侵权请通过评论或 邮件 指出。