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 决定应用启动时的当前工作目录,会影响:
- 相对路径;
- dotenv 查找
.env; - 上传和日志目录;
script相对路径;- 读取模板或静态资源。
不要依赖管理员“恰好在正确目录执行了 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 会带来新的问题:
- 内存 Session 不共享;
- 定时任务可能重复执行;
- 多进程同时写文件;
- 本地缓存不一致;
- 日志来自多个实例;
- WebSocket 需要额外考虑。
等单进程部署、日志、数据库连接和优雅关闭都掌握后,再学习 cluster。
复盘题
- PM2 CLI 退出后,Node.js 应用为什么还能运行?
pm2 stop、delete和kill有什么区别?- 为什么不建议混用普通用户 PM2 和
sudo pm2? pm2 save与pm2 startup分别解决什么问题?- 为什么当前工程先选择 fork 单进程?