1. 项目概述:为什么你需要一份靠谱的PM2命令手册
如果你在Node.js后端开发或者运维的圈子里待过一阵子,PM2这个名字你肯定不陌生。它几乎是Node.js应用在生产环境部署的“标配”进程管理器。我第一次接触PM2,是因为一个线上服务半夜挂了,手动重启后手忙脚乱,后来才知道有这么一个神器,可以守护进程、自动重启、监控日志。但说实话,PM2的命令行接口(CLI)功能非常丰富,多到有时候你明明知道它能做某件事,却记不清具体的命令参数该怎么写。
网上搜“pm2命令”,出来的结果要么是零散的博客片段,要么是官方文档的直译,缺乏场景化的梳理和实战中的“坑点”提示。今天,我就结合自己这些年从踩坑到熟练使用PM2的经历,为你整理一份以场景驱动、附带避坑指南的PM2常用命令汇总。这份汇总不是简单的罗列,我会告诉你每个命令在什么情况下用、为什么要这么用,以及我踩过的那些“雷”。无论你是刚接触PM2的新手,还是想查漏补缺的老手,这份手册都能让你在管理Node.js进程时更加得心应手。
2. PM2核心功能与命令体系解析
在深入具体命令之前,我们得先理解PM2的设计哲学和它的核心能力模型。PM2不仅仅是一个启动脚本的工具,它构建了一个轻量级的“进程管理生态”。
2.1 PM2的四大核心支柱
PM2的强大,建立在四个核心功能之上,我们的命令也基本围绕它们展开:
- 进程生命周期管理:这是基础。包括启动、停止、重启、删除应用。对应的命令如
start,stop,restart,delete。 - 进程状态监控与展示:你需要知道你的应用运行得怎么样。
list(或ls,status) 命令提供了实时快照,而monit命令则提供了一个动态的终端仪表盘。 - 日志集中管理:PM2会自动捕获你应用的标准输出(stdout)和错误输出(stderr),并分别记录到日志文件中。
logs命令是查看日志的入口,flush命令则用于清理日志。 - 集群模式与负载均衡:这是PM2的杀手级功能。通过
-i参数,可以轻松启动多个应用实例(集群),PM2内置的负载均衡器会自动分配流量。这对于利用多核CPU、提高应用性能和可靠性至关重要。
2.2 配置驱动与生态命令
除了直接操作进程的命令,PM2还有两类重要的命令体系:
- 生态系统文件(Ecosystem File):当你的应用需要复杂配置(如环境变量、集群实例数、日志路径等)时,使用一个配置文件(通常是
ecosystem.config.js)是更优雅和可维护的方式。init命令可以生成模板,start和reload命令可以读取该配置。 - 运维与部署命令:包括保存当前进程列表以便开机自启 (
save,startup)、生成系统服务 (startup)、以及简单的性能监控 (pm2 plus相关,但本文聚焦免费核心功能)。
理解了这个体系,我们再看具体命令就不会觉得杂乱无章了。下面,我们就进入实战环节,按使用频率和场景来梳理这些命令。
3. 应用生命周期管理:从启动到下线
这是最常用的一组命令,涵盖了把一个Node.js应用交给PM2管理的全过程。
3.1 启动应用:pm2 start
这是所有故事的开始。但一个简单的start背后有很多门道。
基础用法:
pm2 start app.js这将以独立模式启动app.js,应用名默认为文件名(不含扩展名),即“app”。
进阶配置与场景:
指定应用名:在管理多个应用时,一个好记的名字比脚本名更重要。
pm2 start app.js --name "My-API-Server"监听文件变化并自动重启(开发神器):
pm2 start app.js --watch注意:
--watch会监控整个项目目录的变化。在生产环境慎用,因为频繁的文件变动(如写日志)可能会触发不必要的重启循环。通常仅用于开发环境。传递环境变量:
NODE_ENV=production pm2 start app.js # 或者使用 -- 分隔符传递参数给脚本 pm2 start app.js -- arg1 arg2最大内存重启:防止内存泄漏导致服务器崩溃。
pm2 start app.js --max-memory-restart 300M当应用内存占用超过300MB时,PM2会自动重启它。这个值需要根据你的服务器内存和应用实际情况调整。
实操心得:我习惯在第一次启动非简单应用时,就直接使用生态系统文件,而不是在命令行堆砌大量参数。因为命令行参数不易维护和版本控制。
3.2 查看、停止、重启与删除
- 查看列表:
pm2 list或pm2 ls或pm2 status。这是你最常用的命令之一,一眼看清所有托管应用的状态(online, stopped, errored)、CPU/内存占用、重启次数等。 - 停止应用:
pm2 stop <id|name>。这里的<id|name>可以是pm2 list中看到的数字ID,也可以是你用--name指定的应用名。例如pm2 stop 0或pm2 stop My-API-Server。停止后,应用状态变为stopped,但并未从PM2列表中移除。 - 重启应用:
pm2 restart <id|name>。这会先停止,再启动应用。一个更优雅的命令是reload,我们后面会讲。 - 删除应用:
pm2 delete <id|name>。将应用从PM2列表中彻底移除。如果你想停止并删除,可以用pm2 delete <id|name>;如果只想停止,用stop。
常见问题:pm2 stop all可以停止所有应用,pm2 delete all会删除所有应用(谨慎使用!)。有时候应用卡死,stop无效,可以尝试pm2 kill强制终止PM2守护进程本身(所有托管进程也会停止),然后再启动PM2 (pm2 resurrect需要配合save使用)。
4. 日志管理:定位问题的眼睛
线上应用出了问题,查看日志是第一反应。PM2的日志管理非常规整。
4.1 实时查看日志:pm2 logs
pm2 logs:查看所有托管应用的最新日志(混合输出)。pm2 logs <id|name>:查看指定应用的日志。pm2 logs --lines 200:查看最近200行日志,默认是15行。pm2 logs --err:只查看错误日志。pm2 logs --out:只查看标准输出日志。pm2 logs --raw:显示原始的日志内容,不添加PM2的格式化信息(如时间戳、应用名前缀)。这在需要将日志管道 (pipe) 到其他工具(如grep,awk) 时非常有用。
实操技巧:在调试时,我经常用pm2 logs My-App --err --lines 50快速聚焦最近可能出现的错误。日志默认存储在~/.pm2/logs/目录下,以<app-name>-out.log和<app-name>-error.log分开存储。这个路径可以在启动时通过-o和-e参数自定义。
4.2 清理与重载日志:pm2 flush和pm2 reloadLogs
pm2 flush:这是一个危险但有时必要的命令。它会清空所有PM2管理的日志文件(~/.pm2/logs/下的所有.log文件)。通常在日志文件过大占满磁盘空间,且你已确认历史日志无需保留时使用。重要警告:执行
flush前,请确保已有日志备份或确认可丢弃。生产环境慎用,建议配合日志轮转(log rotation)工具使用。pm2 reloadLogs:这个命令很实用。它会重新打开所有日志文件流。当你使用外部工具(如logrotate)切割或压缩了PM2的日志文件后,需要执行此命令,否则PM2会继续向旧的文件描述符写入,导致日志不记录到新文件。
5. 集群模式与零停机重启
对于Web服务,这是PM2最具价值的功能之一。
5.1 启用集群模式:pm2 start -i
pm2 start app.js -i max:启动与服务器CPU核心数相等的应用实例。PM2会自动创建主进程进行负载均衡。pm2 start app.js -i 4:明确指定启动4个实例。
原理浅析:PM2的集群模式基于Node.js的cluster模块。主进程(Master)不运行你的业务代码,只负责管理一组工作进程(Worker)。当请求到来时,主进程通过轮询等简单策略将其分发给空闲的工作进程,从而充分利用多核CPU。
5.2 优雅重启与重载:reloadvsrestart
这是新手和老手的一个重要分水岭。
pm2 restart <app-name>:硬重启。它会立即终止所有工作进程,然后重新启动它们。这会导致服务在重启期间有短暂的不可用(停机时间)。pm2 reload <app-name>:软重载/零停机重启。这是生产环境的首选。- PM2会启动新的工作进程。
- 等待新的工作进程成功启动并开始监听端口(即“健康”状态)。
- 然后,逐步终止旧的工作进程。
- 在整个过程中,始终有工作进程可以处理请求,从而实现了理论上的“零停机”。
如何实现?你的Node.js应用需要能够优雅地关闭。通常这意味着你的HTTP服务器需要监听SIGINT或SIGTERM信号,在收到信号后停止接收新请求,完成已有请求处理后再退出。许多框架(如Express, Koa)对此有良好支持。
使用场景:当你更新了代码,需要部署新版本时,使用pm2 reload ecosystem.config.js是标准流程。如果reload失败(例如新代码启动报错),PM2会自动回滚到旧版本进程,保证了服务的可用性。
6. 生态系统文件:复杂应用的配置管理
当你的启动命令变成这样时,就该使用生态系统文件了:
pm2 start app.js --name api --watch ./src --ignore-watch="node_modules logs" --max-memory-restart 500M -i 2 --env production --log /var/log/api.log6.1 生成与使用
生成模板:
pm2 init这会生成一个
ecosystem.config.js文件。我强烈推荐使用.js格式而非.json或.yml,因为它允许你使用JavaScript逻辑(如根据环境变量动态配置)。一个典型的配置示例:
module.exports = { apps: [{ name: 'my-app', // 应用名 script: './src/app.js', // 入口脚本 instances: 'max', // 集群实例数,'max' 或数字 exec_mode: 'cluster', // 集群模式 watch: false, // 生产环境关闭监听 max_memory_restart: '1G', // 内存超限重启 env: { // 开发环境变量 NODE_ENV: 'development', PORT: 3000 }, env_production: { // 生产环境变量 (通过 --env production 指定) NODE_ENV: 'production', PORT: 80 }, error_file: './logs/err.log', // 错误日志路径 out_file: './logs/out.log', // 输出日志路径 log_date_format: 'YYYY-MM-DD HH:mm:ss Z' // 日志时间格式 }] };使用配置启动:
# 启动所有应用(使用默认env) pm2 start ecosystem.config.js # 启动并指定使用生产环境变量 pm2 start ecosystem.config.js --env production # 重载配置(零停机) pm2 reload ecosystem.config.js --env production # 仅重启某个应用 pm2 restart ecosystem.config.js --only my-app
配置驱动的优势:版本化、可读性强、环境隔离、便于协作。它把运维配置从口头传递或隐藏的启动脚本中解放了出来。
7. 进程持久化与开机自启
你肯定不希望服务器重启后,需要手动登录再去敲pm2 start。PM2提供了将当前进程列表保存并设置为系统服务的能力。
7.1 保存与恢复进程列表
pm2 save:将当前PM2进程列表(包括所有应用的配置、环境变量等)快照保存到~/.pm2/dump.pm2。这个文件很重要。pm2 resurrect:读取dump.pm2文件,恢复之前保存的所有进程。服务器重启后,如果你手动启动了PM2守护进程,可以执行此命令恢复所有应用。
7.2 配置系统启动服务(以Ubuntu/Debian为例)
这是实现真正开机自启的关键一步。PM2可以帮你生成对应系统的服务脚本(systemd, upstart等)。
生成启动脚本:
pm2 startup执行这个命令,PM2会检测你的系统,并输出一条需要你以root权限执行的命令。例如:
[PM2] Init System found: systemd [PM2] To setup the Startup Script, copy/paste the following command: sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u your_username --hp /home/your_username执行PM2输出的命令:复制上面输出的命令,以root身份执行。这会在
/etc/systemd/system/下创建一个pm2-your_username.service文件。保存当前配置:确保你的应用都已启动,并且是你希望开机自启的状态,然后执行:
pm2 save现在,当服务器重启时,systemd会自动启动PM2守护进程,PM2则会自动加载
dump.pm2并恢复所有应用。
排查技巧:如果开机后应用没起来,首先检查PM2服务状态:sudo systemctl status pm2-your_username。然后检查PM2日志pm2 logs。常见问题是pm2 save没有在正确配置后执行,或者启动脚本中的环境变量PATH不对。
8. 监控、性能排查与高级命令
除了基础管理,PM2也提供了一些内置的监控和诊断工具。
8.1 终端仪表盘:pm2 monit
运行pm2 monit会打开一个基于终端的图形化监控界面。在这里你可以实时看到所有进程的CPU、内存使用情况、日志流,甚至可以进行简单的操作(如重启)。对于快速检查服务器负载情况非常直观。
8.2 简单性能快照
pm2 show <id|name>:显示某个应用的详细信息,包括源码路径、环境变量、循环依赖等元数据。pm2 describe <id|name>:同上,是show的别名。
8.3 环境与版本管理
pm2 --version或pm2 -v:查看PM2版本。pm2 update:更新PM2自身到最新版本。pm2 install <module>:安装PM2模块(PM2早期支持插件系统,但现在很多功能已内置,此命令使用较少)。
9. 常见问题与故障排查实录
即使命令用对了,在实际环境中还是会遇到各种问题。这里记录几个我印象深刻的“坑”。
9.1 应用启动后立即退出,状态为errored
这是最常见的问题。pm2 logs <app-name> --err查看错误日志。
- 原因1:端口被占用。检查日志是否有
EADDRINUSE错误。用netstat -tlnp | grep :<port>查找占用进程并处理。 - 原因2:依赖缺失或Node版本不对。确保在应用目录下执行了
npm install,且Node版本符合要求。PM2启动时会使用系统全局的Node。 - 原因3:配置文件语法错误或路径错误。仔细检查
ecosystem.config.js中的script路径是否正确,JSON/JS语法有无错误。
9.2 集群模式下,工作进程不均衡或部分进程不工作
- 检查负载均衡:PM2集群默认是轮询(round-robin)。如果你的应用有状态(如使用了内存Session),会导致问题。需要确保应用是无状态的,或者将会话存储到外部服务(如Redis)。
- 检查文件描述符限制:启动大量进程可能导致系统文件描述符耗尽。用
ulimit -n查看,必要时增加限制(修改/etc/security/limits.conf)。
9.3pm2 reload不生效或卡住
- 确认应用支持优雅关闭:你的应用必须在收到
SIGINT信号后能正常关闭。可以在代码中添加信号监听器进行测试。process.on('SIGINT', () => { console.log('Received SIGINT. Closing server gracefully...'); server.close(() => { console.log('Server closed.'); process.exit(0); }); }); - 检查
reload超时设置:默认超时时间是1600ms。如果应用关闭较慢,可以通过--kill_timeout <ms>参数增加等待时间。pm2 reload app.js --kill_timeout 5000
9.4 日志文件过大,磁盘空间告警
这是运维中的常态问题。PM2自身没有日志轮转功能,需要借助系统工具。
- 方案一:使用Linux的
logrotate。创建一个配置文件/etc/logrotate.d/pm2:
这个配置会每天轮转日志,保留7天,压缩旧日志,并在轮转后执行/home/username/.pm2/logs/*.log { daily rotate 7 compress delaycompress missingok notifempty create 644 username username sharedscripts postrotate pm2 reloadLogs > /dev/null 2>&1 || true endscript }pm2 reloadLogs让PM2写入新文件。记得将username替换为实际用户。 - 方案二:在生态系统文件中指定日志路径到专门的日志目录,并配合日志收集系统(如ELK, Loki)使用,及时清理本地文件。
9.5 权限问题导致启动失败
- 使用非root用户运行PM2:出于安全考虑,永远不要用root用户直接运行你的Node应用。应该创建一个专用用户(如
deploy)。 - 端口问题:如果你的应用需要监听1024以下的端口(如80、443),非root用户无权限。解决方案是使用反向代理(如Nginx)监听80/443端口,然后转发到Node应用的高端口(如3000),或者使用
authbind、setcap等工具赋予Node程序特定能力。
掌握这些命令和背后的原理,你就能像管理一支训练有素的军队一样管理你的Node.js进程。PM2的工具链思维很清晰:用配置定义状态,用命令触发操作,用日志观察结果。最后记住,任何线上操作,尤其是delete all,flush,kill这类命令,三思而后行,最好先在测试环境验证流程。