03 PM2 原理与基本命令

1. PM2 的基本工作原理

PM2 官方将它描述为 daemon process manager。第一次执行命令时,大致发生:

pm2 CLI
  → 联系或启动当前用户的 PM2 daemon
  → daemon 创建 Node.js 子进程
  → daemon 保存进程状态并收集输出
  → CLI 命令结束
  → daemon 和应用继续在后台运行

所以执行:

pm2 start dist/server.js

并不是让 CLI 永久占住终端,而是让 daemon 接管应用。

2. PM2 是按 Linux 用户隔离的

下面两个用户通常使用不同的 PM2 home 和进程列表:

root    → /root/.pm2
deploy  → /home/deploy/.pm2

因此不要一会儿使用:

pm2 list

一会儿又使用:

sudo pm2 list

后者可能看到 root 用户的另一套进程。建议使用专门的普通部署用户运行应用,只在安装系统服务、修改 Nginx 等必要操作时使用 sudo

3. 安装 PM2

在选定的 NVM Node 版本下:

nvm use 22
npm install --global pm2@latest
pm2 --version
which node
which pm2

which 可以帮助确认 Node 和 PM2 实际来自哪个 NVM 目录。

4. 启动第一个应用

进入项目目录:

cd /var/www/nloop/current
pm2 start dist/server.js --name nloop-api --time

重要参数:

dist/server.js  运行入口
--name          稳定的应用名称
--time          在 PM2 文本日志前添加时间

生产环境不建议使用 --watch 作为默认方案。部署应该明确完成构建和重启,而不是任意文件变化都触发服务重启。

5. 状态和详情命令

pm2 list
pm2 ls
pm2 status

这三个命令都可以查看受管应用列表。

查看某个应用详细信息:

pm2 show nloop-api
pm2 describe nloop-api

观察 CPU 和内存:

pm2 monit

online 只表示进程仍在运行,不代表数据库连接、Nginx 或业务 API 一定正常。因此还需要 /health 检查。

6. 启停命令的区别

pm2 restart nloop-api
pm2 reload nloop-api
pm2 stop nloop-api
pm2 delete nloop-api
pm2 kill
命令 作用
restart 停止并重新启动应用
reload 重新加载应用;零停机优势主要体现在 cluster/多实例
stop 停止应用,但保留在 PM2 列表
delete 停止并从 PM2 列表删除
kill 关闭当前用户的整个 PM2 daemon 及其进程

新人阶段使用 fork 单进程时,更新服务先使用:

pm2 restart nloop-api

它可能产生短暂中断,但行为最容易理解。

7. 日志基本命令

pm2 logs
pm2 logs nloop-api
pm2 logs nloop-api --lines 100
pm2 logs nloop-api --err
pm2 logs nloop-api --out
pm2 logs nloop-api --lines 100 --nostream

清空 PM2 管理的日志:

pm2 flush

flush 是破坏性日志操作,线上执行前要确认是否仍需要保留排障信息。

8. ecosystem 配置文件

命令行适合第一次体验,稳定项目更适合把参数写入配置。当前工程编译为 CommonJS,并且 package.json 没有 "type": "module",因此使用 PM2 官方命名即可:

ecosystem.config.js

最小配置:

module.exports = {
  apps: [
    {
      name: "nloop-api",
      cwd: "/var/www/nloop/current",
      script: "./dist/server.js",
      instances: 1,
      exec_mode: "fork",
      autorestart: true,
      time: true,
      env: {
        NODE_ENV: "production",
        HOST: "127.0.0.1",
        PORT: "8080",
      },
    },
  ],
};

启动:

pm2 start ecosystem.config.js

只操作指定应用:

pm2 restart ecosystem.config.js --only nloop-api
pm2 stop ecosystem.config.js --only nloop-api

9. cwd 为什么重要

cwd 决定应用启动时的当前工作目录,会影响:

不要依赖管理员“恰好在正确目录执行了 pm2 start”。

10. 环境变量更新

修改 ecosystem 的环境变量后:

pm2 restart ecosystem.config.js --only nloop-api --update-env

如果应用自己通过 dotenv 读取 .env,进程重启后通常会重新读取文件;--update-env 主要用于刷新 PM2 注入或 shell 环境变量。仍建议使用它明确表达更新意图。

11. 保存和手动恢复进程列表

应用验证成功后:

pm2 save

它保存的是当前 PM2 进程列表快照。手动恢复:

pm2 resurrect

注意:

pm2 save     保存“将来要恢复什么”
pm2 startup  配置“开机时由谁启动恢复过程”

两者用途不同,开机恢复通常都需要。

12. 不要一开始使用 cluster

初版保持:

instances: 1,
exec_mode: "fork",

cluster 会带来新的问题:

等单进程部署、日志、数据库连接和优雅关闭都掌握后,再学习 cluster。

复盘题

  1. PM2 CLI 退出后,Node.js 应用为什么还能运行?
  2. pm2 stopdeletekill 有什么区别?
  3. 为什么不建议混用普通用户 PM2 和 sudo pm2
  4. pm2 savepm2 startup 分别解决什么问题?
  5. 为什么当前工程先选择 fork 单进程?

官方参考