快速入门:跑通你的第一个应用
定位:动手课。跟着敲一遍,20 分钟内获得"我已经会日常使用 PM2"的手感。
前置:一台 Linux 机器,已装 Node.js(建议 LTS),已读 核心概念
安装 PM2
PM2 是 npm 包,装法本质都是“全局装一次,得到同一个 pm2 命令”。任选一种即可,默认推荐方式一(npm)。前三种方式都要求本机已有 Node.js(PM2 7.x 需 Node ≥ 18)。
方式一:npm(最通用、默认推荐)
npm install -g pm2 # 全局安装方式二:yarn
yarn global add pm2仅 Yarn 1.x(Classic)可用;Yarn 2+(Berry)已移除
yarn global命令,用 Berry 时请退回 npm / pnpm。
方式三:pnpm
pnpm add -g pm2若装完提示
pm2: command not found,多半是 pnpm 的全局 bin 目录不在 PATH:执行pnpm bin -g查看该目录,把它加进 PATH 即可。
方式四:apt(Debian/Ubuntu 的官方 .deb)——版本滞后,仅特殊场景
先破除一个常见误区:Debian/Ubuntu 的官方软件源里并没有 pm2 这个包,直接 apt install pm2 会报 Unable to locate package pm2。官方文档提供的 Debian/Ubuntu 装法,是先用它的安装脚本添加 PM2 官方 apt 仓库(脚本会顺带装 Node LTS):
sudo apt update && sudo apt install -y curl
curl -sL https://raw.githubusercontent.com/Unitech/pm2/master/packager/setup.deb.sh | sudo -E bash -
# 脚本结束会提示把当前用户加入 pm2 组——重新登录一次后再使用 pm2⚠️ 不推荐日常/生产使用:PM2 这个官方 apt 仓库(packagecloud 的
Keymetrics/pm2)已多年不更新(撰写时最新仍是 3.2.x,而 npm 上已是 7.x),远落后于本文 5.x–7.x 的叙述范围,与新版 Node 的兼容性也无保证;脚本本身还依赖apt-key等过时做法。只有“必须用 .deb 做系统级管理、或环境禁止访问 npm 源”时才考虑。不想要时可sudo apt remove pm2,再回到 npm 安装。
任选一种装完后,验证一下:
pm2 -v # 验证版本(如 7.x.x,依所装版本而定)npm 全局目录没有写权限时会报
EACCES,处置见 故障排查与最佳实践;生产环境建议用普通用户安装、避免用 root 跑应用。以后升级 PM2 后记得执行一次pm2 update(见 命令速查)。
安装后第一次执行任意 pm2 命令(如 pm2 ls),会自动在后台启动 daemon:
pm2 ls
# 首次输出类似:
# ┌──────┬────┬─────────┬─────────┬─────┬────────┬──────────┐
# │ name │ id │ mode │ status │ ↺ │ cpu │ memory │
# └──────┴────┴─────────┴─────────┴─────┴────────┴──────────┘看到一张空表格 = daemon 已就绪。可以用 pm2 ping 确认 daemon 存活。
写一个"待托管"的应用
新建 app.js,一个极简 HTTP 服务(后面所有演示都用它):
// app.js —— 一个简单的可观测服务
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end(`hello from pid=${process.pid} time=${new Date().toISOString()}\n`);
});
// 故意周期性打印一些日志,方便观察日志功能
setInterval(() => console.log('tick', new Date().toISOString()), 5000);
server.listen(3000, () => console.log('listening on 3000, pid=' + process.pid));直接验证它能跑:
node app.js & # 前台/后台跑一下
curl http://127.0.0.1:3000 # 应返回 hello from pid=...
kill %1 # 或 Ctrl+C,关掉手工进程交给 PM2 托管
pm2 start app.js --name demo输出一张表格,重点看这几列:
| 列 | 含义 |
|---|---|
id | PM2 分配的进程编号(从 0 开始) |
name | 应用名,这里是 demo |
mode | fork(或 cluster,见 集群模式与零停机发布) |
↺ | 重启次数(restarts) |
status | 应为 online |
cpu / memory | 实时资源占用 |
验证服务真的在跑,并且跟你的终端无关:
curl http://127.0.0.1:3000
# hello from pid=12345 ...
# 把当前 shell 关掉/退出登录,再开一个新终端:
pm2 ls # demo 依然 online
curl http://127.0.0.1:3000 # 依然有响应 —— 这就是"守护"的意义观察:日志与监控
pm2 logs demo # 实时跟随 demo 的输出(console.log / console.error)
# 每 5 秒能看到一行 tick ...;Ctrl+C 退出查看(进程不受影响)
pm2 logs demo --lines 100 # 回看最近 100 行
pm2 logs demo --err # 只看错误输出
pm2 monit # 全屏监控面板:实时 CPU/内存/日志(按 q 退出)日志的落盘位置、时间戳、轮转等详见 日志与轮转。
做一次"崩溃演习"
体会 PM2 的自动重启。给进程发个致命的未捕获异常信号:
# 让 demo 进程崩溃:给它发 SIGKILL(模拟 OOM 被杀 / 进程崩溃)
pm2 pid demo # 拿到 PID
kill -9 $(pm2 pid demo)
sleep 1
pm2 ls
# 你会看到 demo 依然 online,但 ↺(重启次数)变成了 1 —— 它被自动拉起来了
curl http://127.0.0.1:3000 # 服务"没断"结论:异常退出 → 自动重启。这也是"应用为什么莫名其妙重启过 N 次"的答案——去查
↺列和重启策略(监控与告警)。
日常管理五件套
pm2 restart demo # 重启:先停旧进程再起新进程(有短暂中断)
pm2 stop demo # 停止:进程退出,但记录仍在列表里(status=stopped)
pm2 start demo # 把已 stop 的进程再次启动(不是重复加一条!)
pm2 delete demo # 彻底删除:停止并从列表移除,日志文件保留在磁盘
# 想顺带改参数可以:
pm2 restart demo --update-env # 重启并重新加载当前 shell 的环境变量
pm2 restart demo --time # 之后日志自动带时间戳记笔记:
- stop 是"暂停",delete 是"删除"。新手最容易把 delete 当 stop 用。
pm2 restart是"杀旧起新";想少中断请用reload(仅 cluster,见 集群模式与零停机发布)。- 命令都可以用名字或 id:
pm2 restart demo与pm2 restart 0等价。
用配置文件代替手敲参数
刚才所有选项都是命令行传的。进程一多、参数一长,就该写配置文件了。把上面过程变成声明式:
// ecosystem.config.js
module.exports = {
apps: [
{
name: 'demo',
script: 'app.js',
instances: 1, // 1 个实例
exec_mode: 'fork', // fork 模式
max_memory_restart: '200M', // 内存超过 200M 自动重启(见 06)
time: true, // 日志行自动加时间戳(另一种写法:log_date_format 自定义格式,见 05)
env: {
NODE_ENV: 'development',
},
env_production: {
NODE_ENV: 'production',
},
},
],
};pm2 start ecosystem.config.js # 用默认 env 启动
pm2 start ecosystem.config.js --env production # 注入 env_production 并启动
pm2 delete all # 清掉本次演示的所有进程注意:日志时间戳相关配置(
time/log_date_format)的取舍详见 日志与轮转;其余字段详解见 配置文件(先照抄即可)。
配置文件(.js 或 .json/.cjs)里能配置的东西非常多,字段逐个详解见 配置文件。
生产收尾:保存 + 开机自启
pm2 save # 把当前进程清单存为快照(dump.pm2)
pm2 startup # 按输出提示,把那条 sudo 命令执行一遍(注册 systemd 单元)原理与细节(包括如何卸载自启)在 开机自启与远程部署。
本课小结:你已会的 vs 待学
| 已掌握 | 下一步去学 |
|---|---|
| 安装、start / ls / logs / monit | 命令全集 → 命令速查 |
| restart / stop / delete、崩溃演习 | 重启策略细节 → 监控与告警 |
| 配置文件 + --env | 字段详解 → 配置文件 |
| save / startup | systemd 原理与部署 → 开机自启与远程部署 |
| fork 模式单实例 | 多核与零停机 → 集群模式与零停机发布 |
参考链接
- 官方快速开始:https://pm2.keymetrics.io/docs/usage/quick-start/
- 官方安装指南(含 yarn、apt/.deb 安装脚本):https://pm2.io/docs/runtime/guide/installation/
- PM2 官方 apt 仓库(可自查版本是否滞后):https://packagecloud.io/Keymetrics/pm2
