Node.js 部署与进程管理完全指南:PM2 实战
PM2 简介
PM2(Process Manager 2)是 Node.js 生态中最流行的进程管理工具,支持进程守护、负载均衡、日志管理、零配置热重载、远程监控等功能。使用 npm install -g pm2 全局安装。
基础命令
# 启动应用(自动检测入口文件)
pm2 start app.js
# 启动并指定应用名称
pm2 start app.js --name my-api
# 启动带环境变量
pm2 start app.js --name my-api --env production
# 查看进程列表
pm2 list
# 等价于
pm2 status
# 查看详细日志
pm2 logs my-api
# 查看特定行数日志
pm2 logs my-api --lines 50
# 重启应用(先停止再启动)
pm2 restart my-api
# 重新加载(零 downtime,针对集群)
pm2 reload my-api
# 停止应用
pm2 stop my-api
# 删除应用(从 PM2 管理列表中移除)
pm2 delete my-api
# 查看监控面板(实时 CPU/内存)
pm2 monit
# 查看应用详细信息
pm2 show my-api
ecosystem.config.js 配置文件
推荐使用配置文件管理多应用部署:
// ecosystem.config.js
module.exports = {
apps: [
{
// ===== 基本配置 =====
name: 'my-api', // 应用名称
script: './src/index.js', // 入口脚本
args: '--env production', // 启动参数
cwd: './', // 工作目录
// ===== 资源限制 =====
instances: 4, // 进程数量(max 表示 CPU 核心数)
exec_mode: 'cluster', // 'cluster'(集群)或 'fork'(默认)
max_memory_restart: '512M', // 内存超限自动重启
// ===== 环境变量 =====
env: {
NODE_ENV: 'development',
PORT: 3000
},
env_production: {
NODE_ENV: 'production',
PORT: 3000
},
// ===== 日志配置 =====
log_file: './logs/combined.log', // 所有日志
out_file: './logs/out.log', // stdout
error_file: './logs/error.log', // stderr
log_date_format: 'YYYY-MM-DD HH:mm:ss',
merge_logs: true, // 多进程日志合并
// ===== 进程策略 =====
autorestart: true, // 崩溃自动重启
watch: false, // 生产环境关闭 watch
max_restarts: 10, // 最大重启次数
min_uptime: '10s', // 认为正常的最短运行时间
restart_delay: 4000, // 重启延迟(毫秒)
// ===== 其他 =====
node_args: '--max-old-space-size=4096', // Node 参数
source_map_support: true, // Source Map 支持
kill_timeout: 5000, // 等待进程优雅退出的时间
listen_timeout: 3000 // 应用启动超时
},
// 第二个应用示例
{
name: 'worker',
script: './workers/sync.js',
instances: 2,
exec_mode: 'fork',
cron_restart: '0 3 * * *', // 每天凌晨 3 点重启(定时任务)
env: {
NODE_ENV: 'production'
}
}
]
};
启动命令
# 使用配置文件启动
pm2 start ecosystem.config.js
# 指定环境(--env 参数选择 env_XXX 配置)
pm2 start ecosystem.config.js --env production
# 只启动第一个应用
pm2 start ecosystem.config.js --only my-api
# 启动所有应用
pm2 start ecosystem.config.js --only 'my-api,worker'
集群模式与负载均衡
PM2 的集群模式利用 Node.js 内置的 cluster 模块,实现多进程负载均衡,无需修改代码:
# 启动 4 个进程(自动分配负载)
pm2 start app.js -i 4 --name my-api
# 使用 max 自动匹配 CPU 核心数
pm2 start app.js -i max --name my-api
# 动态调整进程数
pm2 scale my-api +3 # 增加 3 个进程
pm2 scale my-api 8 # 调整为 8 个进程
pm2 scale my-api 0 # 停止所有进程
重要注意:集群模式下,应用需要是无状态的(不存储内存数据),因为不同请求可能被分配到不同进程。Session 和缓存数据必须存储在 Redis 等外部存储中。
Docker 集成
# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY . .
COPY .env.production .env
EXPOSE 3000
# 使用 tini 作为 PID 1init 进程,正确处理信号
RUN apt-get update && apt-get install -y tini && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["pm2-runtime", "start", "ecosystem.config.js", "--env", "production"]
# docker-compose.yml
version: '3.8'
services:
api:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
env_file:
- .env.production
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1'
memory: 1G
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
日志管理
# 查看日志(实时追踪)
pm2 logs my-api --lines 100 --nostream
# 日志分割(使用 logrotate)
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M # 单个日志文件最大 10MB
pm2 set pm2-logrotate:retain 7 # 保留 7 个文件
pm2 set pm2-logrotate:compress true # 压缩旧日志
# 清空日志(不停止应用)
pm2 flush my-api
# 将日志重定向到 syslog
pm2 start app.js --syslog
系统启动脚本
# 生成启动脚本(根据系统 init 方式自动选择)
pm2 startup
# 保存当前进程列表(下次开机自动恢复)
pm2 save
# 查看启动配置命令
pm2 unstartup
# systemd 手动配置示例
# 将以下内容写入 /etc/systemd/system/my-api.service
# [Unit]
# Description=My Node.js API
# After=network.target
#
# [Service]
# Type=simple
# User=ubuntu
# WorkingDirectory=/home/ubuntu/my-api
# ExecStart=/usr/bin/env pm2 start ecosystem.config.js --env production
# Restart=on-failure
# RestartSec=10
# StandardOutput=syslog
# StandardError=syslog
# SyslogIdentifier=my-api
# Environment=NODE_ENV=production
#
# [Install]
# WantedBy=multi-user.target
PM2 Plus 监控(可选)
PM2 Plus 是付费监控服务,提供 Web UI、异常告警、性能指标:
# 本地部署 PM2 Plus
pm2 link <secret-key> <public-key>
# 查看在线仪表盘
pm2 plus
对于免费替代方案,推荐使用:
- <strong>Prometheus + Grafana</strong> — 自建监控系统
- <strong>PM2 的内置 API</strong> — <code>pm2 list</code> / <code>pm2 jlist</code> 获取 JSON 格式状态
- <strong>日志服务</strong> — ELK Stack(Elasticsearch + Logstash + Kibana)
常见问题
Q1: PM2 集群模式和 Nginx 负载均衡哪个更好?
两者可以叠加使用。PM2 集群模式在单台服务器内实现多核利用(利用多核 CPU);Nginx 作为反向代理,在多台服务器间分配流量。建议:小项目(<4 核)只用 PM2 集群;大项目(多台服务器)PM2 集群 + Nginx 负载均衡。
Q2: PM2 重启后数据丢失怎么办?
PM2 的 pm2 save 只能保存进程列表,无法保存应用数据。应用数据必须存储到持久化存储(MySQL、MongoDB、Redis、文件系统等)。PM2 重启不等于应用数据丢失——如果数据丢失,说明设计有问题(内存数据没有定期持久化)。
Q3: 如何排查 PM2 进程崩溃的原因?
1. pm2 logs my-api --err --lines 100 查看错误日志
2. pm2 describe my-api 查看进程详情(重启次数、内存、CPU)
3. pm2 monit 实时观察资源使用
4. 检查 .pm2/pm2.log 中的系统级错误
5. 确保 .pm2/pids/ 中的 PID 与实际进程匹配
6. 检查系统 OOM(Out Of Memory)日志:dmesg | grep -i "out of memory"
延伸阅读
- <a href="https://pm2.keymetrics.io/docs/usage/quick-start/">PM2 官方文档</a>
- <a href="https://pm2.io/">PM2 Plus 监控平台</a>
- <a href="https://expressjs.com/zh-cn/advanced/best-practice-performance.html">Node.js 生产环境最佳实践</a>