简介
PM2 是 node 进程管理工具,可以利用它来简化很多 node 应用管理的繁琐任务,如性能监控、自动重启、负载均衡等,而且使用非常简单
安装&更新&基本使用
npm install pm2 -g 或 yarn global add pm2
// 查看PM2的版本
pm2 -version
// 更新
pm2 updated 或 npm install pm2@latest -g启动项目
node ./main.js // node 启动方式
pm2 start ./main.js // pm2 启动方式常用参数
可追加参数更好的执行程序,如:
pm2 start "需要启动的文件" --watch --env production
--watch 参数,当你的应用代码发生变化时,pm2 会重启服务
--env production 启动时指定环境变量(需配合配置文件中的 `env_prod` 字段)部分常用参数如下:
--watch:监听应用目录的变化,一旦发生变化,自动重启;-i --instances:启用多少个实例,可用于负载均衡。--instances是具体个数或者max,max则根据当前机器核数确定实例数目;--name "my-app":为应用指定自定义名称;--max-memory-restart 1024M:当内存使用超过 1024MB 时自动重启进程-o --output <path>:标准输出日志文件的路径;日志默认存储在
$HOME/.pm2/logs/目录下xxx-out.log(标准输出)-e --error <path>:错误输出日志文件的路径;日志默认存储在
$HOME/.pm2/logs/目录下xxx-err.log(错误输出)--node-args="--harmony":传递 Node.js 引擎参数(如启用 ES6+ 特性);--ignore-watch:排除监听的目录/文件,可以是特定的文件名,也可以是正则;--interpreter <interpreter>:the interpreter pm2 should use for executing app (bash, python...)。比如你用的 coffee script 来编写应用;--attach: 启动的同时检测日志流-x:用fork模式启动 app.js 而不是使用 cluster
进程管理
pm2 start:启动应用;pm2 update:保存进程,中止 pm2 并恢复进程;pm2 startup [name]:实现开机自启动;- 保存当前进程列表
[platform]; pm2 startup [platform]:根据当前进程配置进行自启动
- 保存当前进程列表
pm2 list或pm2 ls:列出所有由 PM2 管理的应用进程;pm2 monit:实时监控进程的 CPU 和内存使用情况;pm2 show [app-name|id]:查看指定应用的详细信息(包括启动时间、内存、日志路径等);pm2 save:保存当前进程列表;pm2 serve:启动一个静态 web 服务;pm2 serve [跟目录] [端口] --name [pm2名称]
pm2 resurrect:恢复以前保存的进程;pm2 unstartup:停用和删除自动启动配置;pm2 logs:实时查看所有应用的日志输出;pm2 logs --json:日志 json 化
pm2 stop [app-name|id|all]:停止指定应用;pm2 restart [app-name|id|all]:重启指定应用(会中断服务);pm2 gracefulReload all:平稳的重新加载所有应用;pm2 reload [app-name|id|all]:在集群模式下实现零停机重启;pm2 delete [app-name|id|all]:从 PM2 管理列表中移除应用;pm2 delete all:停止并删除所有管理的应用;pm2 scale [app-name] 10:将指定应用的实例数动态扩展到 10 个;PM2 flush:清楚日志;PM2 reloadLogs:重载日志;pm2 generate:生成样本 json 配置文件;
端口占用解决
在运行应用的时候可能会遇到 address already in use :::XXX 报错,该错误是因为应用运行端口被占用导致,解决办法如下:
查看服务器防火墙是否放行端口;
在终端中查看端口占用情况
lsof -i tcp:[应用端口号],在输出的接口中可以看到下列信息;
| 字段名 | 说明 |
|---|---|
| COMMAND | 进程名称 |
| PID | 进程标识符 |
| USER | 进程所有者 |
| FD | 文件描述符,应用程序通过文件描述符识别该文件 |
| TYPE | 文件类型,文件 REG、目录 DIR、字符 CHR、块设备 BLK、UNIX 域套接字 UNIX、先进先出队列 FIFO、IP 套接字 IPv4 |
| DEVICE | 指定磁盘的名称 |
| SIZE/OFF | 文件的大小 |
| NODE | 索引节点(文件在磁盘上的标识) |
| NAME | 打开文件的确切名称 |
kill [PID]杀死进程;
还有另一种方式:
- 在得到进程信息后,可以根据
PID的内容对比pm2 list应用列表中所有应用的PID来锁定占用应用; - 使用
pm2 stop [app-name|id]停止该应用;
自动化部署
本人目前没有尝试过自动化部署,以下内容仅作为知识储备以便后期查阅
自动化部署需要保证服务器上拥有 pm2 环境,如果没有需运行 npm install pm2 -g 安装
pm2 ecosystem // 生成配置文件 ecosystem.config.js
pm2 init // 初始化配置文件module.exports = {
apps : [{ // json 结构,apps 是一个数组,每一个数组成员就是对应一个 pm2 中运行的应用
name: 'API', // 应用名
script: 'app.js', // 应用文件位置
cwd: "./", // 根目录
args: "", // 传递给脚本的参数
interpreter: "", // 指定的脚本解释器
interpreter_args: "", // 传递给解释器的参数
watch: true, // 是否监听文件变动然后重启
ignore_watch: [ // 不用监听的文件
"node_modules",
"logs"
],
exec_mode: "cluster_mode", // 应用启动模式,支持 fork 和 cluster 模式
instances: 4, // 应用启动实例个数,仅在 cluster 模式有效 默认为fork;或者 max
max_memory_restart: 8, // 最大内存限制数,超出自动重启
error_file: "./logs/app-err.log", // 错误日志文件
out_file: "./logs/app-out.log", // 正常日志文件
merge_logs: true, // 设置追加日志而不是新建日志
log_date_format: "YYYY-MM-DD HH:mm:ss", // 指定日志文件的时间格式
min_uptime: "60s", // 应用运行少于时间被认为是异常启动
max_restarts: 30, // 最大异常重启次数,即小于 min_uptime 运行时间重启次数;
autorestart: true, // 默认为 true, 发生异常的情况下自动重启
cron_restart: "", // crontab 时间格式重启应用,目前只支持 cluster 模式;
restart_delay: "60s" // 异常重启情况下,延时重启时间
env: { // 生产环境
PM2_SERVE_PATH: ".", // 静态服务路径
PM2_SERVE_PORT: 8080, // 静态服务器访问端口
NODE_ENV: 'development', // 启动默认模式,当前指定为生产环境 process.env.NODE_ENV
REMOTE_ADDR: "http://www.example.com/"
},
env_dev : { // 开发环境
NODE_ENV: 'production', // 使用 production 模式 pm2 start ecosystem.config.js --env production
REMOTE_ADDR: "http://wdev.example.com/"
},
env_test: { // 测试环境
NODE_ENV: 'production', // 使用 development 模式 pm2 start ecosystem.config.js --env development
REMOTE_ADDR: "http://wtest.example.com/"
},
instances:"max", // 将应用程序分布在所有 CPU 核心上,可以是整数或负数
watch:true, // 监听模式
ignore_watch:["node_modules"], // 忽略监视的文件或目录
watch_options:{ // 监视选项
"followSymlinks": false
},
output: './out.log', // 指定日志标准输出文件及位置
error: './error.log', // 错误输出日志文件及位置,pm2 install pm2-logrotate进行日志文件拆分
merge_logs: true, //集群情况下,可以合并日志
log_type:"json", // 日志类型
log_date_format: "DD-MM-YYYY", // 日志日期记录格式
args: ["--port", "3000"], // 传递给应用程序的参数
exec_mode:'cluster', // 执行模式,可以是 fork 或 cluster
max_memory_restart:"200M", // 当进程使用的内存超过指定的值时,自动重启进程
}],
// 部署配置
deploy : {
production : {
user: "root", // 服务器登录用户名
host: ["192.168.1.100"], // 服务器IP(支持数组配置多台服务器)
ref: "origin/main", // 要部署的 Git 分支(如 main/master)
repo: "git@github.com:your-name/your-project.git", // Git 仓库地址(SSH 形式)
path: "/www/my-node-app", // 服务器上的部署目录(需提前创建)
// 部署后执行的命令(核心:安装依赖、重启服务)
"post-deploy": "npm install && pm2 reload ecosystem.config.js --env production",
// 可选:部署前执行的命令
"pre-deploy": "echo '开始部署生产环境...'",
// 可选:首次部署时执行的命令(如创建目录)
"pre-setup": "mkdir -p /www/my-node-app"
}
}
}执行部署命令
| 命令 | 作用 |
|---|---|
| pm2 deploy ecosystem.config.js production setup | 首次部署:初始化服务器部署目录(仅需执行一次) |
| pm2 deploy ecosystem.config.js production | 修改配置后提交 |
| pm2 deploy production | 部署生产环境(简写,默认读取 ecosystem.config.js) |
| pm2 deploy production --force | 强制提交 |
| pm2 deploy production status | 查看部署状态 |
| pm2 deploy production revert | 回滚到上一个版本 |
| pm2 deploy production exec "npm run build" | 在服务器执行指定命令(如构建前端代码) |
