全栈手账 订阅 RSS
PM2

PM2 基础知识与常用命令总结

PM2 进程管理器使用手册:涵盖安装、启停与重启、日志管理、ecosystem.config.js 配置、cluster 集群模式与开机自启,是 Node.js 应用在生产环境稳定运行的必备工具。

读了 29 分钟 更新于 8 月 12 日

一、PM2 基础概念

1. 什么是 PM2?

  • Node.js 进程管理工具
  • 生产环境下管理 Node.js 应用的守护进程
  • 提供自动重启、负载均衡、日志管理、监控等功能
  • 适用于 Node.js 项目(NestJS、Express、Koa、Egg.js 等)

2. 为什么需要 PM2?

问题 没有 PM2 有 PM2
进程崩溃 服务直接挂掉,需手动重启 自动重启,零停机
多核利用 单进程,浪费 CPU 集群模式,充分利用多核
日志管理 手动处理,容易丢失 自动分日志文件,支持轮转
开机自启 需写 systemd 配置 一条命令搞定
进程监控 需额外工具 内置监控面板
环境管理 手动切环境变量 配置文件统一管理

3. PM2 核心特点

  • 内建负载均衡:基于 Node.js cluster 模块
  • 零停机重启:pm2 reload 逐个重启进程
  • 自动重启:进程崩溃或文件变化时自动重启
  • 日志系统:stdout/stderr 分离,支持日志轮转
  • 生产就绪:支持开机自启、信号处理、优雅关闭

二、安装与环境要求

1. 前置条件

  • 已安装 Node.js(建议 16+)
  • 已安装 npm

2. 全局安装 PM2

bash
# 全局安装npm install -g pm2# 验证安装pm2 --version# 查看帮助pm2 --help

3. 更新 PM2

bash
# 更新 PM2 自身npm install -g pm2@latest# 更新 PM2 后,更新已运行的进程(使其加载新 PM2)pm2 update

三、进程管理命令

1. 启动应用

bash
# 基本启动pm2 start app.js# 启动并命名进程pm2 start app.js --name "my-api"# 启动并指定实例数(集群模式)pm2 start app.js -i 4          # 启动 4 个实例pm2 start app.js -i max        # 按 CPU 核心数启动pm2 start app.js -i 0          # 同 max# 启动并监听文件变化(开发模式)pm2 start app.js --watch# 启动并指定环境变量pm2 start app.js --env production# 启动并传参pm2 start app.js -- --port 3000

2. 启动 NestJS 项目

bash
# 编译项目npm run build# 用 PM2 启动编译后的入口文件pm2 start dist/main.js --name "nest-api"# 集群模式启动pm2 start dist/main.js -i max --name "nest-api"# 使用 ts-node 直接启动(开发环境)pm2 start src/main.ts --name "nest-dev" --interpreter ts-node

3. 停止进程

bash
# 停止指定进程pm2 stop my-api              # 按名称pm2 stop 0                   # 按 IDpm2 stop all                 # 停止所有进程# 停止并从 PM2 列表中删除pm2 delete my-api            # 按名称删除pm2 delete 0                 # 按 ID 删除pm2 delete all               # 删除所有进程

4. 重启进程

bash
# 重启(杀掉再启动,有短暂中断)pm2 restart my-apipm2 restart all# 优雅重载(逐个重启,零停机,仅集群模式有效)pm2 reload my-apipm2 gracefulReload my-api    # 同上,更明确

restart vs reload 的区别:

操作 行为 停机时间 适用场景
restart 杀掉所有进程,重新启动 有 单进程、紧急重启
reload 逐个重启进程 零 集群模式、生产环境更新

5. 进程状态速查

bash
# 查看所有进程pm2 listpm2 ls                       # 简写# 查看详细信息pm2 show my-api              # 查看指定进程详情pm2 info 0                   # 按 ID 查看

pm2 list 输出示例:

code
┌────┬──────────────┬─────────────┬──────────┬──────────┬──────────┐│ id │ name         │ mode        │ ↺        │ status   │ cpu      │├────┼──────────────┼─────────────┼──────────┼──────────┼──────────┤│ 0  │ nest-api     │ cluster     │ 2        │ online   │ 0.5%     ││ 1  │ nest-worker  │ fork        │ 0        │ online   │ 0.3%     │└────┴──────────────┴─────────────┴──────────┴──────────┴──────────┘
字段 说明
id 进程 ID
name 进程名称
mode 运行模式(fork=单进程,cluster=集群)
↺ 重启次数
status 状态(online/errored/stopped)
cpu CPU 占用率

四、监控与调试

1. 实时监控面板

bash
# 打开终端监控面板(类似 top 命令)pm2 monit

监控面板包含:

  • 进程列表(CPU、内存使用率)
  • 实时日志输出
  • 左右切换面板

2. 查看日志

bash
# 查看所有进程日志pm2 logs# 查看指定进程日志pm2 logs my-api# 只看最近 50 行pm2 logs my-api --lines 50# 实时监听日志(默认行为)pm2 logs my-api# 只看错误日志pm2 logs my-api --err# 只看输出日志pm2 logs my-api --out# 清空所有日志pm2 flush# 清空指定进程日志pm2 flush my-api

3. 查看进程资源消耗

bash
# 查看所有进程的 CPU 和内存pm2 prettylist              # JSON 格式详细信息# 查看指定进程详情pm2 describe my-apipm2 desc 0                  # 简写

pm2 describe 输出包含:

  • 进程路径、启动参数
  • 运行时间、重启次数
  • 内存使用(RSS、heap used、heap total)
  • 日志文件路径
  • 执行模式、PID

五、配置文件(ecosystem.config.js)

1. 创建配置文件

bash
# 生成配置文件模板pm2 initpm2 ecosystem                # 同上

2. 完整配置示例

javascript
// ecosystem.config.jsmodule.exports = {  apps: [    {      name: 'nest-api',              // 进程名称      script: 'dist/main.js',        // 入口文件      instances: 'max',              // 实例数(max=CPU核心数,或数字)      exec_mode: 'cluster',          // 运行模式(cluster/fork)      cwd: './',                     // 工作目录      watch: false,                  // 是否监听文件变化      env: {                         // 默认环境变量(开发)        NODE_ENV: 'development',        PORT: 3000,        DB_HOST: 'localhost',        DB_PORT: 3306,        DB_NAME: 'miracle_dev',      },      env_production: {              // 生产环境变量        NODE_ENV: 'production',        PORT: 3000,        DB_HOST: '127.0.0.1',        DB_PORT: 3306,        DB_NAME: 'miracle',        REDIS_HOST: '127.0.0.1',        REDIS_PORT: 6379,      },      // 日志配置      out_file: './logs/out.log',    // 标准输出日志      error_file: './logs/error.log',// 错误日志      merge_logs: true,              // 集群模式下合并日志      log_date_format: 'YYYY-MM-DD HH:mm:ss',  // 日志加时间戳      // 重启策略      max_restarts: 10,              // 最大重启次数      restart_delay: 3000,           // 重启间隔(毫秒)      max_memory_restart: '1G',      // 内存超过 1G 自动重启      // 优雅关闭      kill_timeout: 3000,            // 发送 kill 信号后等待时间      listen_timeout: 8000,          // 启动超时时间    },    // 可以配置多个应用    {      name: 'nest-worker',           // 另一个进程(如消息队列消费者)      script: 'dist/worker.js',      instances: 1,      exec_mode: 'fork',      env_production: {        NODE_ENV: 'production',      },    },  ],};

3. 使用配置文件启动

bash
# 使用配置文件启动(默认环境)pm2 start ecosystem.config.js# 使用生产环境配置启动pm2 start ecosystem.config.js --env production# 重启配置文件中的所有应用pm2 restart ecosystem.config.js --env production# 重载(零停机)pm2 reload ecosystem.config.js --env production# 停止pm2 stop ecosystem.config.js# 删除pm2 delete ecosystem.config.js

4. 常用配置项速查

配置项 类型 说明
name string 进程名称
script string 入口文件路径
instances number/string 实例数(max/数字)
exec_mode string cluster 或 fork
cwd string 工作目录
watch boolean/string 文件监听(可指定目录)
env object 默认环境变量
env_production object 生产环境变量
env_development object 开发环境变量
out_file string 输出日志路径
error_file string 错误日志路径
merge_logs boolean 合并集群日志
log_date_format string 日志时间戳格式
max_restarts number 最大重启次数
restart_delay number 重启延迟(毫秒)
max_memory_restart string 内存超限自动重启
kill_timeout number 优雅关闭超时
listen_timeout number 启动就绪超时

六、集群模式

1. 集群模式 vs Fork 模式

维度 fork 模式 cluster 模式
进程数 单进程 多进程(按 CPU 核心)
多核利用 否 是
负载均衡 无 内置(轮询)
零停机重载 不支持 支持(reload)
共享端口 不支持 支持(自动共享)
适用场景 定时任务、消费者 Web 服务、API 服务

2. 启动集群模式

bash
# 按 CPU 核心数启动pm2 start dist/main.js -i max --name "nest-api"# 指定实例数pm2 start dist/main.js -i 4 --name "nest-api"# 在配置文件中指定module.exports = {  apps: [{    name: 'nest-api',    script: 'dist/main.js',    instances: 'max',        // 集群模式    exec_mode: 'cluster',  }],};

3. 集群模式下的操作

bash
# 零停机重载(逐个重启)pm2 reload nest-api# 查看集群状态pm2 list                     # mode 列显示 cluster# 增减实例数(需要先 delete 再重新 start)pm2 delete nest-apipm2 start ecosystem.config.js --env production

4. 集群模式注意事项

  • 共享端口:所有实例共享同一个端口(如 3000),PM2 自动处理
  • Session 问题:集群模式下 Session 不能存在内存中,必须用 Redis 存储
  • WebSocket:长连接会固定在某个实例上,需要用 Redis Pub/Sub 跨实例通信
  • 文件操作:多实例同时写文件会冲突,需用锁机制或由单独的 worker 处理

七、日志管理

1. 日志文件位置

默认日志路径:~/.pm2/logs/

code
~/.pm2/logs/├── nest-api-out.log       # 标准输出日志├── nest-api-error.log     # 错误日志├── nest-worker-out.log└── nest-worker-error.log

2. 自定义日志路径

在配置文件中指定:

javascript
{  out_file: './logs/out.log',  error_file: './logs/error.log',  log_date_format: 'YYYY-MM-DD HH:mm:ss',  merge_logs: true,}

3. 日志轮转(logrotate)

PM2 自带日志轮转模块:

bash
# 安装日志轮转模块pm2 install pm2-logrotate# 查看当前配置pm2 conf pm2-logrotate# 修改配置pm2 set pm2-logrotate:max_size 10M           # 单个日志文件最大 10Mpm2 set pm2-logrotate:retain 30              # 保留 30 个日志文件pm2 set pm2-logrotate:compress true          # 压缩旧日志pm2 set pm2-logrotate:dateFormat YYYY-MM-DD  # 日志文件日期格式pm2 set pm2-logrotate:workerInterval 30      # 检查间隔(秒)pm2 set pm2-logrotate:rotateInterval '0 0 * * *'  # 每天午夜轮转

4. 日志命令汇总

bash
pm2 logs                     # 查看所有日志(实时)pm2 logs my-api              # 查看指定进程日志pm2 logs my-api --lines 100  # 查看最近 100 行pm2 logs my-api --err        # 只看错误日志pm2 flush                    # 清空所有日志pm2 flush my-api             # 清空指定进程日志

八、开机自启动

1. 生成开机自启脚本

bash
# 保存当前 PM2 进程列表(必须先执行,再设置自启)pm2 save# 生成并安装系统启动脚本pm2 startup                  # 自动检测系统类型# 指定系统类型pm2 startup systemd          # Linux systemdpm2 startup launchd          # macOSpm2 startup upstart          # Ubuntu 老版本

执行 pm2 startup 后会输出一条命令,复制执行即可:

bash
# 输出示例(需要复制执行)[PM2] To setup the Startup Script, copy/paste the following command:sudo env PATH=$PATH:/usr/local/bin pm2 startup systemd -u youruser --hp /home/youruser

2. 保存与恢复进程列表

bash
# 保存当前运行的进程列表pm2 save# 手动恢复(通常开机自启会自动执行)pm2 resurrect# 查看保存的进程列表cat ~/.pm2/dump.pm2

3. 取消开机自启

bash
# 取消开机自启pm2 unstartup# 指定系统类型取消pm2 unstartup systemd

4. 完整流程(首次配置)

bash
# 1. 启动你的应用pm2 start ecosystem.config.js --env production# 2. 保存进程列表pm2 save# 3. 设置开机自启(复制输出的命令执行)pm2 startup# 4. 完成,重启服务器验证sudo reboot

九、生产环境实战配置

1. NestJS 项目完整配置

javascript
// ecosystem.config.jsmodule.exports = {  apps: [    {      name: 'nest-api',      script: 'dist/main.js',      instances: 'max',      exec_mode: 'cluster',      // 生产环境变量      env_production: {        NODE_ENV: 'production',        PORT: 3000,      },      // 日志      out_file: '/var/log/nest-api/out.log',      error_file: '/var/log/nest-api/error.log',      merge_logs: true,      log_date_format: 'YYYY-MM-DD HH:mm:ss Z',      // 自动重启策略      max_restarts: 10,      restart_delay: 3000,      max_memory_restart: '1G',      // 优雅关闭      kill_timeout: 5000,      listen_timeout: 10000,    },  ],};

2. 部署流程

bash
# 1. 拉取最新代码git pull origin main# 2. 安装依赖npm install# 3. 编译npm run build# 4. 零停机重载pm2 reload ecosystem.config.js --env production# 5. 确认状态pm2 listpm2 logs nest-api --lines 20

3. 一键部署脚本

bash
#!/bin/bash# deploy.shset -eecho "==> 拉取代码..."git pull origin mainecho "==> 安装依赖..."npm install --production=falseecho "==> 编译项目..."npm run buildecho "==> 重载 PM2(零停机)..."pm2 reload ecosystem.config.js --env productionecho "==> 保存进程列表..."pm2 saveecho "==> 部署完成!"pm2 list

使用方式:

bash
chmod +x deploy.sh./deploy.sh

十、常用命令速查表

进程管理

命令 说明
pm2 start app.js 启动应用
pm2 start app.js --name "myapp" 启动并命名
pm2 start app.js -i max 集群模式启动
pm2 start app.js --watch 文件变化自动重启
pm2 stop myapp 停止进程
pm2 stop all 停止所有进程
pm2 restart myapp 重启进程
pm2 reload myapp 零停机重载(集群模式)
pm2 delete myapp 停止并删除进程
pm2 delete all 删除所有进程

查看状态

命令 说明
pm2 list 查看进程列表
pm2 show myapp 查看进程详情
pm2 monit 实时监控面板
pm2 describe myapp 查看详细信息
pm2 prettylist JSON 格式查看所有进程

日志

命令 说明
pm2 logs 查看所有日志
pm2 logs myapp 查看指定进程日志
pm2 logs myapp --lines 50 查看最近 50 行
pm2 logs myapp --err 只看错误日志
pm2 flush 清空所有日志

配置与自启

命令 说明
pm2 init 生成配置文件模板
pm2 start ecosystem.config.js 用配置文件启动
pm2 start ecosystem.config.js --env production 用生产环境配置启动
pm2 save 保存当前进程列表
pm2 startup 设置开机自启
pm2 unstartup 取消开机自启
pm2 resurrect 恢复保存的进程列表

模块管理

命令 说明
pm2 install pm2-logrotate 安装模块
pm2 uninstall pm2-logrotate 卸载模块
pm2 list 也可查看已安装模块
pm2 conf 查看模块配置

十一、常见面试题

基础概念

Q1:PM2 是什么?解决了什么问题?

  • Node.js 生产环境进程管理工具
  • 解决 Node.js 单进程崩溃后无法自动恢复的问题
  • 提供集群模式实现多核负载均衡
  • 提供日志管理、监控、开机自启等生产级功能

Q2:PM2 的 fork 模式和 cluster 模式有什么区别?

维度 fork cluster
进程数 1 个 多个(按 CPU 核心)
多核利用 否 是
负载均衡 无 内置轮询
共享端口 否 是
零停机重载 不支持 支持
适用场景 消费者、定时任务 Web 服务

Q3:pm2 restart 和 pm2 reload 有什么区别?

  • restart:杀掉所有进程再重新启动,有短暂停机
  • reload:逐个重启进程,实现零停机,仅 cluster 模式有效
  • 生产环境更新代码应使用 reload

进阶问题

Q4:PM2 集群模式下如何处理 Session?

  • 集群模式有多个进程实例,内存中的 Session 不共享
  • 必须将 Session 存储到外部(如 Redis)
  • NestJS 中用 @nestjs-modules/ioredis 或 connect-redis 实现

Q5:PM2 集群模式下 WebSocket 怎么处理?

  • WebSocket 长连接会固定在某一个实例上
  • 跨实例通信需要用 Redis Pub/Sub
  • 或者使用第三方服务(如腾讯云 IM)来处理实时通信

Q6:如何实现 PM2 的零停机部署?

bash
# 1. 编译新代码npm run build# 2. 零停机重载pm2 reload ecosystem.config.js --env production
  • reload 会逐个重启实例,总有一个实例在处理请求
  • 前提是 cluster 模式且 instances > 1

Q7:PM2 的 max_memory_restart 是怎么工作的?

  • PM2 定期检查进程内存使用量
  • 超过设定值时自动重启该进程
  • 防止内存泄漏导致服务器崩溃
  • 示例:max_memory_restart: '1G'

Q8:PM2 如何实现开机自启动?

  • pm2 startup 生成系统启动脚本(systemd/launchd)
  • pm2 save 保存当前进程列表到 ~/.pm2/dump.pm2
  • 系统启动时自动执行 PM2,恢复保存的进程列表

实战经验

Q9:PM2 启动后进程频繁重启怎么办?

  • 检查错误日志:pm2 logs myapp --err
  • 常见原因:
    • 端口被占用
    • 环境变量缺失
    • 代码有语法错误
    • 依赖未安装
  • 检查 restart_delay 设置,避免重启风暴

Q10:如何查看 PM2 进程的实际 PID?

bash
pm2 describe myapp | grep pid# 或pm2 prettylist | grep pid

Q11:PM2 日志文件越来越大怎么办?

  • 安装 pm2-logrotate 模块实现日志轮转
  • 设置 max_size(如 10M)自动切割
  • 设置 retain(如 30)限制保留数量
  • 或用 Linux 的 logrotate 工具管理

Q12:如何在不停止服务的情况下更新代码?

bash
# 方式1:文件监听模式(开发环境)pm2 start app.js --watch# 方式2:编译后 reload(生产环境推荐)npm run buildpm2 reload ecosystem.config.js --env production

十二、常见问题与注意事项

1. 端口被占用

bash
# 查看端口占用lsof -i :3000          # Linux/Macnetstat -ano | findstr :3000   # Windows# 杀掉占用进程kill -9 <PID># 重新启动pm2 start ecosystem.config.js --env production

2. PM2 命令找不到

bash
# PM2 全局安装路径没在 PATH 中npm install -g pm2# 查找 PM2 路径which pm2# 或npm root -g# 手动创建软链接ln -s /usr/local/lib/node_modules/pm2/bin/pm2 /usr/local/bin/pm2

3. 集群模式下内存泄漏

javascript
// 在配置文件中设置内存上限自动重启{  max_memory_restart: '1G',}

同时要排查代码中的内存泄漏:

  • 未清除的定时器
  • 闭包引用
  • 全局变量无限增长
  • 事件监听器未移除

4. 日志时区问题

javascript
// 在配置文件中设置时区格式{  log_date_format: 'YYYY-MM-DD HH:mm:ss Z',  // 或使用本地时间  tz: 'Asia/Shanghai',}

5. 优雅关闭(Graceful Shutdown)

NestJS 中需要处理 PM2 发送的关闭信号:

typescript
// main.tsimport { NestFactory } from '@nestjs/core';async function bootstrap() {  const app = await NestFactory.create(AppModule);  await app.listen(3000);  // 优雅关闭  process.on('SIGINT', async () => {    await app.close();    process.exit(0);  });  process.on('SIGTERM', async () => {    await app.close();    process.exit(0);  });}bootstrap();

PM2 配置中设置关闭超时:

javascript
{  kill_timeout: 5000,    // 给应用 5 秒时间优雅关闭}

6. 环境变量管理

bash
# 直接在命令行传环境变量PORT=3000 pm2 start dist/main.js --name "nest-api"# 在配置文件中管理(推荐)module.exports = {  apps: [{    name: 'nest-api',    script: 'dist/main.js',    env_production: {      PORT: 3000,      DB_HOST: '127.0.0.1',    },  }],};# 使用 .env 文件(配合 dotenv)// 在 NestJS 中通过 @nestjs/config 读取 .env 文件

十三、总结

PM2 是 Node.js 生产环境部署的标配工具,核心能力:

能力 说明
进程守护 崩溃自动重启
集群模式 多核负载均衡
零停机部署 reload 逐个重启
日志管理 stdout/stderr 分离 + 轮转
监控 内置 CPU/内存监控
开机自启 一条命令搞定

生产环境最佳实践:

  • 用 ecosystem.config.js 管理配置,不要裸命令启动
  • 用 --env production 区分环境
  • 用 reload 而非 restart 做更新
  • 用 pm2-logrotate 管理日志大小
  • 用 pm2 save + pm2 startup 设置开机自启
  • 用 max_memory_restart 防止内存泄漏
  • 集群模式下 Session 和 WebSocket 走 Redis

前端、后端、部署、客服都是我一个人。写这里的东西都是真踩过的坑,不是抄来的教程。