PM2进程管理与集群模式
1. 概念
PM2 是 Node.js 生产首选进程管理器。解决:
- 单线程 Node 挂了自动重启
- 利用多核(cluster 模式)
- 零停机重启(graceful reload)
- 日志管理
- 内存 / CPU 监控
2. 安装与基础
npm install -g pm2
# 启动
pm2 start server.js --name myapp
# 查看
pm2 list
pm2 show myapp
# 日志
pm2 logs myapp --lines 100
pm2 logs --json
# 重启
pm2 restart myapp
pm2 reload myapp # 零停机重启
# 停止 / 删除
pm2 stop myapp
pm2 delete myapp
3. ecosystem.config.js
// ecosystem.config.js
module.exports = {
apps: [{
name: 'myapp',
script: 'dist/server.js',
instances: 'max', // cluster 模式用所有核
exec_mode: 'cluster', // fork | cluster
// 资源限制
max_memory_restart: '1G', // 超 1G 自动重启
max_restarts: 10,
min_uptime: '10s', // 启动 10s 内崩算异常(不算正常重启)
// 环境变量
env: {
NODE_ENV: 'development',
},
env_production: {
NODE_ENV: 'production',
PORT: 3000,
},
// 日志
error_file: '/var/log/pm2/myapp-error.log',
out_file: '/var/log/pm2/myapp-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
merge_logs: true, // cluster 模式合并日志
// 监听文件变化(开发用)
watch: false,
// Node 参数
node_args: '--max-old-space-size=1536',
// 优雅退出
kill_timeout: 10000, // 等 SIGTERM 10s
listen_timeout: 8000, // reload 等新进程 ready 8s
wait_ready: true, // 等应用发 process.send('ready')
}]
}
pm2 start ecosystem.config.js --env production
pm2 reload ecosystem.config.js --env production
4. Cluster 模式
PM2 用 Node cluster 模块 fork 多进程:
PM2 (master)
├── Worker 1 (CPU 0)
├── Worker 2 (CPU 1)
├── Worker 3 (CPU 2)
└── Worker 4 (CPU 3)
instances: 'max' 按 CPU 核数。K8s 容器里 CPU limit 2 核时 instances: 2。
4.1 状态共享问题
Cluster 模式每进程独立内存。session、缓存不能存 memory:
- Session → Redis
- 缓存 → Redis / Memcached
- 文件上传 → 对象存储(不落本地)
5. 零停机重启(Graceful Reload)
pm2 reload myapp
原理:
- PM2 fork 新 worker
- 新 worker 就绪(send('ready') 或 listen 成功)
- PM2 给老 worker SIGINT
- 老 worker 处理完当前请求后退出
- 所有老 worker 替换完成
应用必须实现:
const server = app.listen(3000, () => {
process.send?.('ready') // 告诉 PM2 就绪
})
process.on('SIGINT', () => {
server.close(() => {
process.exit(0)
})
})
6. 开机启动
# 生成启动脚本
pm2 startup
# 输出一条命令,复制执行
# 保存当前进程列表
pm2 save
# 以后重启机器自动恢复
7. 监控
# 终端看板
pm2 monit
# Web 仪表盘(需要 pm2 plus 账号)
pm2 plus
pm2 monit 看实时 CPU、内存、loop delay。
8. 日志管理
# 清空日志
pm2 flush
# 日志轮转
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true
或配合系统 logrotate(见模块 01)。
9. PM2 vs 容器(K8s)
| 场景 | 推荐 |
|---|---|
| 单台服务器 | PM2 |
| K8s | 不需要 PM2,K8s 做重启 + HPA 做多副本 |
| K8s 但要 cluster 模式 | PM2 在容器内跑,或 replicas N 代替 |
K8s 里 PM2 cluster: max 的问题:HPA 基于 Pod CPU 决策,PM2 多进程让每 Pod CPU 跑满但 HPA 不知道。建议 K8s 用多 replicas(每 Pod 跑 1 进程)+ HPA。
10. 故障排查
# 进程一直 restart
pm2 logs myapp --lines 200
pm2 show myapp
# 看 restart count / uptime
# 内存泄漏
pm2 show myapp
# 看 memory 趋势
# 连不上
pm2 list
# 看 status: online / stopped / errored
11. 常见反模式
- Cluster 模式 + 内存 session:跨进程不共享
- 不设
max_memory_restart:内存泄漏撑死 - reload 不实现优雅退出:正在处理的请求被截断
instances: max在低配机器:CPU 核多但内存不够- 日志不 rotate:写满磁盘
- K8s 里 pm2 instances max:和 HPA 冲突
- 不用
wait_ready:新进程还没 listen 就接流量