Skip to main content

PM2

PM2 是一个带有内置负载均衡器的 Node.js 应用程序进程管理器。它可以让应用程序永远保持活跃,无需停机即可重新加载它们,并简化常见的系统管理任务。

1. 基础使用

1.1 安装

# 全局安装 PM2
npm install pm2 -g

# 更新 PM2
pm2 update

1.2 基本命令

# 启动应用
pm2 start app.js

# 启动应用并命名
pm2 start app.js --name "my-app"

# 启动 npm 命令
pm2 start npm -- start

# 集群模式启动
pm2 start app.js -i max # 根据CPU核心数启动最大进程数
pm2 start app.js -i 4 # 启动4个进程

# 监控文件变化自动重启
pm2 start app.js --watch

# 列出所有进程
pm2 list

# 显示进程详细信息
pm2 show <app-name>

# 显示日志
pm2 logs
pm2 logs <app-name>

# 重启应用
pm2 restart <app-name>

# 停止应用
pm2 stop <app-name>

# 删除应用
pm2 delete <app-name>

# 清空所有日志
pm2 flush

2. 配置文件

2.1 生态系统文件

// ecosystem.config.js
module.exports = {
apps: [{
name: "app",
script: "./app.js",
instances: "max",
exec_mode: "cluster",
watch: true,
env: {
NODE_ENV: "development",
},
env_production: {
NODE_ENV: "production",
}
}, {
name: 'worker',
script: 'worker.js'
}]
}

// 使用配置文件
pm2 start ecosystem.config.js // 使用开发环境配置
pm2 start ecosystem.config.js --env production // 使用生产环境配置

2.2 高级配置选项

module.exports = {
apps: [{
name: "app",
script: "./app.js",

// 进程配置
instances: 4,
exec_mode: "cluster",

// 重启配置
autorestart: true,
max_restarts: 10,

// 内存配置
max_memory_restart: "1G",

// 日志配置
log_date_format: "YYYY-MM-DD HH:mm:ss",
error_file: "logs/error.log",
out_file: "logs/out.log",
merge_logs: true,

// 监控配置
watch: ["server", "client"],
ignore_watch: ["node_modules", "logs"],
watch_options: {
followSymlinks: false
},

// 环境变量
env: {
NODE_ENV: "development",
PORT: 3000
},
env_production: {
NODE_ENV: "production",
PORT: 80
}
}]
}

3. 集群模式

3.1 负载均衡

# 启动集群
pm2 start app.js -i max # 根据 CPU 核心数启动最大进程数
pm2 start app.js -i 0 # 同上
pm2 start app.js -i 4 # 启动4个进程

# 扩展/收缩集群
pm2 scale app +3 # 增加3个进程
pm2 scale app 2 # 设置为2个进程

# 重新加载集群
pm2 reload app # 零停机重新加载

3.2 集群配置

module.exports = {
apps: [{
script: 'app.js',
instances: 4,
exec_mode: 'cluster',
instance_var: 'INSTANCE_ID',
increment_var: 'PORT',
env: {
PORT: 3000
}
}]
}

4. 监控和日志

4.1 监控

# 启动监控界面
pm2 monit

# 查看仪表板
pm2 plus # 启动 web 界面监控

# 状态
pm2 status

# 性能指标
pm2 prettylist

4.2 日志管理

# 查看日志
pm2 logs [app-name] # 显示指定应用的日志
pm2 logs --lines 200 # 显示最后200行日志
pm2 logs --timestamp # 显示带时间戳的日志

# 日志轮转
pm2 install pm2-logrotate

# 配置日志轮转
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true

5. 部署

5.1 部署配置

// ecosystem.config.js
module.exports = {
apps: [{
name: 'app',
script: 'app.js'
}],
deploy: {
production: {
user: 'node',
host: '212.83.163.1',
ref: 'origin/master',
repo: 'git@github.com:repo.git',
path: '/var/www/production',
'post-deploy': 'npm install && pm2 reload ecosystem.config.js --env production'
}
}
}

// 部署命令
pm2 deploy production setup # 首次设置
pm2 deploy production # 部署
pm2 deploy production revert # 回滚

5.2 启动脚本

# 生成启动脚本
pm2 startup

# 保存当前进程列表
pm2 save

# 恢复保存的进程
pm2 resurrect

6. 集成和插件

6.1 常用插件

# 安装日志轮转插件
pm2 install pm2-logrotate

# 安装监控插件
pm2 install pm2-server-monit

# 安装 Slack 通知插件
pm2 install pm2-slack

# 查看已安装插件
pm2 list modules

6.2 API 集成

const pm2 = require('pm2');

// 连接到 PM2
pm2.connect(function(err) {
if (err) {
console.error(err);
process.exit(2);
}

// 启动应用
pm2.start({
script: 'app.js',
name: 'app'
}, function(err, apps) {
if (err) {
console.error(err);
return pm2.disconnect();
}

// 列出所有进程
pm2.list((err, list) => {
console.log(list);
pm2.disconnect();
});
});
});

7. 最佳实践

7.1 性能优化

module.exports = {
apps: [{
name: 'api',
script: 'app.js',
instances: 'max',
exec_mode: 'cluster',
max_memory_restart: '1G',
node_args: '--max_old_space_size=1024',
exp_backoff_restart_delay: 100,
combine_logs: true,
merge_logs: true,
error_file: '/var/log/pm2/api.error.log',
out_file: '/var/log/pm2/api.out.log'
}]
}

7.2 安全建议

module.exports = {
apps: [{
name: 'api',
script: 'app.js',
// 限制权限
user: 'www-data',
group: 'www-data',

// 错误处理
max_restarts: 10,
min_uptime: '5s',

// 日志安全
log_type: 'json',
error_file: '/var/log/pm2/error.log',
out_file: '/var/log/pm2/out.log',

// 环境隔离
node_args: '--no-deprecation --no-warnings',
env: {
NODE_ENV: 'production'
}
}]
}

参考资源