跳转到内容
KN郑某某

PM2 入门教程:Node.js 进程管理利器

PM2 是 Node.js 生产环境必备的进程管理工具,本文从安装到进阶,带你掌握守护进程、日志管理、集群模式等核心功能。

工具 1 分钟阅读

直接用 node app.js 启动应用,终端关闭进程就挂了。PM2 解决的问题:

  • 守护进程:崩溃自动重启,进程意外退出自动恢复
  • 负载均衡:利用多核 CPU,自动分配请求
  • 日志管理:统一管理 stdout/stderr,支持日志轮转
  • 零停机重启:更新代码时不断开连接
  • 开机自启:服务器重启后自动拉起进程

Terminal window
# 全局安装
npm install -g pm2
# 验证
pm2 --version

Terminal window
# 启动单个文件
pm2 start app.js
# 指定应用名称
pm2 start app.js --name my-app
# 启动并指定 Node 参数
pm2 start app.js --node-args="--max-old-space-size=4096"

Terminal window
# 查看所有进程
pm2 list
# 停止进程
pm2 stop my-app
# 重启进程
pm2 restart my-app
# 删除进程(从列表移除)
pm2 delete my-app
# 重启所有进程
pm2 restart all

Terminal window
# 查看进程详细信息
pm2 describe my-app
# 查看进程树
pm2 tree

生产环境推荐使用配置文件管理进程。

Terminal window
# 生成配置文件模板
pm2 ecosystem

ecosystem.config.js
module.exports = {
apps: [{
name: 'my-app',
script: './app.js',
instances: 'max', // 使用所有CPU核心
exec_mode: 'cluster', // 集群模式
env: {
NODE_ENV: 'development',
PORT: 3000
},
env_production: {
NODE_ENV: 'production',
PORT: 8080
}
}]
};

Terminal window
# 启动
pm2 start ecosystem.config.js
# 指定环境启动
pm2 start ecosystem.config.js --env production
# 重新加载配置
pm2 reload ecosystem.config.js

module.exports = {
apps: [{
name: 'my-app',
script: './app.js',
// 实例配置
instances: 4, // 固定4个实例
// instances: 'max', // 或使用所有CPU
exec_mode: 'cluster', // cluster 或 fork
// 重启策略
max_restarts: 10, // 最大重启次数
min_uptime: '10s', // 最小运行时间(视为成功启动)
restart_delay: 5000, // 重启间隔(毫秒)
// 内存限制
max_memory_restart: '1G', // 内存超1G自动重启
// 日志配置
log_file: './logs/app.log',
error_file: './logs/error.log',
out_file: './logs/output.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss',
// 环境变量
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}]
};

Terminal window
# 实时查看所有日志
pm2 logs
# 查看指定进程日志
pm2 logs my-app
# 查看错误日志
pm2 logs --err
# 查看输出日志
pm2 logs --out
# 退出日志监控
# 按 Ctrl+C

Terminal window
# 安装日志轮转模块
pm2 install pm2-logrotate
# 配置
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true

Terminal window
# 启动监控面板
pm2 monit

监控面板显示:

  • CPU 使用率
  • 内存占用
  • 进程状态
  • 日志输出

Terminal window
# 保存当前进程列表
pm2 save
# 恢复之前保存的进程列表
pm2 resurrect
# 清除保存的进程列表
pm2 unstartup

Terminal window
# 生成开机自启脚本
pm2 startup
# 按照提示执行输出的命令,例如:
# sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u xiaya --hp /home/xiaya
# 保存进程列表
pm2 save

Terminal window
# 零停机重启(cluster模式)
pm2 reload my-app
# 应用代码中配合处理
process.send('ready');

在应用中等待连接处理完毕再退出:

const http = require('http');
const server = http.createServer((req, res) => {
res.end('Hello World');
});
server.listen(3000, () => {
// 告诉 PM2 应用已就绪
if (process.send) {
process.send('ready');
}
});
// 优雅关闭
process.on('SIGINT', () => {
server.close(() => {
process.exit(0);
});
});

module.exports = {
apps: [{
name: 'my-app',
script: './app.js',
// 每天凌晨3点重启
cron_restart: '0 3 * * *'
}]
};

module.exports = {
apps: [{
name: 'my-app',
script: './app.js',
// 内存超500M重启
max_memory_restart: '500M',
// 或使用正则匹配内存值
// max_memory_restart: '/^1[0-9]{3}$/' // 1000-1999MB
}]
};

Terminal window
# ecosystem.config.js
module.exports = {
apps: [{
name: 'my-app',
script: './app.js'
}],
deploy: {
production: {
user: 'xiaya',
host: 'your-server.com',
ref: 'origin/main',
repo: '[email protected]:user/repo.git',
path: '/var/www/production',
'pre-deploy-local': "echo 'Deploying...'",
'post-deploy': 'npm install && pm2 reload ecosystem.config.js --env production'
}
}
};
Terminal window
# 部署命令
pm2 deploy ecosystem.config.js production setup
pm2 deploy ecosystem.config.js production

Terminal window
pm2 start server.js --name web-server

Terminal window
pm2 start npm --name "next-app" -- run start

Terminal window
pm2 start socket-server.js --name socket-io

cron-job.js
const cron = require('node-cron');
cron.schedule('0 * * * *', () => {
console.log('执行定时任务...');
// 业务逻辑
});
// 启动
// pm2 start cron-job.js --name cron-task

Terminal window
pm2 list
pm2 describe my-app

Terminal window
pm2 logs --err --lines 100

Terminal window
pm2 restart my-app
pm2 logs my-app --lines 50

进程反复重启

  • 检查错误日志:pm2 logs --err
  • 确认代码是否有语法错误
  • 检查端口是否被占用

内存占用过高

  • 配置 max_memory_restart
  • 检查是否有内存泄漏

集群模式下报错

  • 确保应用是无状态的
  • 使用 pm2 reload 而不是 pm2 restart

评论