进程管理主要是指创建,终止和监控进程。进程管理器主要是用来确保你的应用在启动后能够保持在线
pm2 是 nodejs 的进程管理器,默认支持负载均衡,能够守护进程。还支持查看应用运行时的性能,资源占用情况等
不管发生上面哪种情况,都会造成服务的不可访问,需要等我们自己去发现问题后,然后重启应用。
# 没有nodejs的需要首先安装
# 安装地址http://nodejs.cn/download/
# 有问题
wget https://nodejs.org/dist/v18.14.2/node-v18.14.2-linux-x64.tar.xz
tar -xvf node-v18.14.2-linux-x64.tar.xz
mv node-v18.14.2-linux-x64 /usr/local/
cd /usr/local/nodejs/bin
./node -v
# 全局
sudo vim /etc/profile
export NODE_HOME=/usr/local/node
export PATH=$NODE_HOME/bin:$PATH
source /etc/profile
#安装pm2
npm install pm2 -g
# pm2有两种模式,开发模式和生产模式
# 开发 node 应用的时候,修改代码过后每次都要重启下应用,很麻烦。使用 pm2-dev 命令启动应用,应用会在在代码发生变更过后,自动重启
pm2-dev start server.js
# 应用部署到生产环境后,可以使用 pm2 start 来启动应用,命令启动的应用,默认支持进程守护,并且可以通过 pm2 进行监控
pm2 start server.js
# 启动指定应用,如pm2 start index.js --name httpServer;
pm2 start <script_file|config_file> [options]
# 支持不同文件格式
pm2 start app.js
pm2 start bashscript.sh
pm2 start python-app.py
pm2 start binary-file
pm2 start "npm run start"
pm2 start "ls -la"
pm2 start app.py
# 设置启动应用的显示名称
pm2 start app.js --name <app_name>
# 监控应用目录,一旦有文件发生更改就立刻重启应用
pm2 start app.js --watch
# 指定日志输出目录
pm2 start app.js --log <log_path>
# 设置应用重启时,能使用内存的最大值
pm2 start app.js --max-memory-restart <200MB>
# 启动时,传递参数给 app 应用
pm2 start app.js -- arg1 arg2 arg3
# 禁止自动重启应用
pm2 start app.js --no-autorestart
# 定时任务。可以设置 一天中的固定重启时间, 一周内固定重启日期,或者 一个时间间隔(如 每 48 小时重启一次)
# cron_pattern参考:https://www.npmjs.com/package/cron
pm2 start app.js --cron <cron_pattern>
# 固定延时重启,这里的2000单位为毫秒,即在需要重启的时候等待两秒钟
pm2 start --restart-delay=2000
# 灵活延时,重试时间会随着重试次数增多不断延长
# 此处的1000单位也是毫秒,PM2会在多次重启失败后以设定的时间为初始值,使用指数移动平均算法不断延长重试时间,最高为15000毫秒(即15秒),并在进程成功启动30秒后重置重试时间到到初始值
pm2 start --exp-backoff-restart-delay=1000
# 静态服务器,将目录dist作为静态服务器根目录,端口为9090
pm2 serve ./dist 9090
app_name
的位置除了传应用名,还可以传:
all
针对所有进程进行操作id
针对特定id的进程进行操作集群模式下,restart中断服务,而reload不会
# ------------------------------重启、重载、停止、删除------------------------
# 停止指定应用,如pm2 stop httpServer;
# 也可以执行他目录下得 pm2-start.sh 脚本里面用. pm2-start.sh 执行输入0就可以关闭在执行得脚本
# (app_name|app_id|all)
pm2 stop [options]
# 重启指定应用,如pm2 restart httpServer;
pm2 reload|restart [options]
# 显示指定应用详情,如pm2 show httpServer;
pm2 show [options]
# 删除指定应用,如pm2 delete httpServer,如果修改应用配置行为,最好先删除应用后,重新启动方才生效,如修改脚本入口文件;
pm2 delete [options]
# 重置 restart 的计时器
pm2 reset all
# 杀掉pm2管理的所有进程;
pm2 kill
# 保存并恢复PM2进程
pm2 update
#----------------------------查看运行状态-------------------------
# 查看所有进程信息(app_name、app_id等)
pm2 [list|ls|status]
# 对应用进行排序查看
pm2 list --sort name:desc
# Or
pm2 list --sort [name|id|pid|memory|cpu|status|uptime][:asc|desc]
# 查看某个应用详情
pm2 describe app_name|app_id
# 查看应用详情信息
pm2 show app_name|app_id
# 清除保存的应用列表
pm2 cleardump
# 保存当前应用列表,以后可以恢复
pm2 save # 同 pm2 dump
# 重新加载之前保存的应用列表
pm2 resurrect
运行pm2 list
的命令后,可以查看所有 pm2 启动的应用
id
:应用 idname
:应用名称namespace
:在配置文件里面可以给应用设置 namespace。设置后可以使用命令行单独启动或停止某个 namespace 的应用mode
: 进程的运行方式。分为 fork
与 cluster
pid
:进程iduptime
:运行时间↺
:重启次数(从0开始计数)status
:进程是否在线cpu
:cpu占用率mem
:内存占用大小而pm2 show app_name|app_id
查看应用详情信息,除了 pm2 list
命令返回的信息以外,还可以获取几个常用信息
script path
:启动入口的文件路径script args
:启动文件的参数error log path
:错误日志的文件路径out log path
:输出日志的文件路径exec mode
:进程的模式watch&reload
:是否开启监听文件变动重启unstable restarts
:不稳定的重启次数# 查看指定应用的日志,即标准输出和标准错误;
pm2 logs [options] [id|name|namespace]
pm2 logs
# 还可以直接进入日志保存的目录查看
# 监控各个应用进程cpu和memory使用情况
pm2 monit
# 查看所有命令
pm2 --help
#or
pm2 -h
官方参考:https://pm2.keymetrics.io/docs/usage/application-declaration/
当我们需要管理多个应用,或者应用有多个运行环境时,使用 pm2 start
来启动应用+配置参数是很不方便的。所以,pm2 支持使用配置文件来启动和管理应用。
# 生成配置文件
pm2 init simple
# 运行该命令可在工程下初始化一个 ecosystem.config.js 配置文件
module.exports = {
apps : [{
name : "app1",
script : "./app.js"
}]
}
# apps是要管理应用的数组,每个对象都是一个应用的配置
# 你也可以自己创建一个配置文件,文件名以 .config.js 结尾,pm2 会自动识别并读取该文件
# Start all applications
pm2 start ecosystem.config.js
# Stop all
pm2 stop ecosystem.config.js
# Restart all
pm2 restart ecosystem.config.js
# Reload all
pm2 reload ecosystem.config.js
# Delete all
pm2 delete ecosystem.config.js
基础配置
进阶配置
cluster
或 fork
,默认为 fork
false
。如果设置成 true
,当应用程序变动时,pm2会自动重载ignore_watch: [
'node_modules',
'logs',
]
max_memory_restart :应用运行内存达到设定值后,会自动重启。避免了 Node.js heap out of memory error
问题
env :应用中的默认环境变量
env_ :命令行中可传入的环境变量,覆盖默认环境变量
source_map_support :默认 true
,支持 sourcemap 文件
日志配置
控制流
error
前,一定时间(min_uptime
指定的时间,若未配置,则为 1 秒)内的连续不稳定重启次数# 以上两个配置项一般需要同时设置,以下举个例子
# server.js
setTimeout(function () {
console.log('killed');
process.exit(1)
}, 1000);
# ecosystem.config.js
module.exports = {
apps: [{
name: "app-market",
script: "./server.js",
max_restarts: 4,
min_uptime: 5000,
}]
}
# server 应用在启动 1s 后,会自己强行结束进程。这时, pm2 由于进程守护的特性,会去重新拉起应用。
# 示例中设置了 min_uptime 为 5000(即 5s),max_restarts 为 4 次,所以 pm2 在进程停止(1s)后去重启进程,5s 钟可以内重启次数肯定可以达到 4 次。达到设定次数后,则停止重启应用
ready
信号,间隔多长时间 reload。单位为毫秒。ready
信号。默认为 false
。设置为 true
后,需要在应用内部添加 process.send('ready')
语句发送 ready
信号。以上两个配置项一般需要搭配使用,详细使用场景见 优雅的启动与停止应用
module.exports = {
apps : [{
name: 'app',
script: './app.js',
kill_timeout: 3000
}]
}
当 pm2 要停止或重启一个应用时,会按顺序给你的进程发送一系列系统信号。它首先会发送一个 SIGINT
信号告诉你应用将会被停止。然后 pm2 会等待 3s(示例中 kill_timeout
设置的时间)。若 3s 后应用没有自己停止(exit),pm2 会发送一个 SIGKILL
信号来强制停止应用。优雅停止
# 启动、停止、重启、重载、删除配置文件中所有项目
pm2 start ecosystem.config.js
pm2 stop ecosystem.config.js
pm2 restart ecosystem.config.js
pm2 reload ecosystem.config.js
pm2 delete ecosystem.config.js
# 启动指定应用
pm2 start ecosystem.config.js --only api-app
pm2 start ecosystem.config.js --only "api-app,worker-app"
# 命令行启动
# max 的意思是:把应用部署到服务器所有可用的CPU上,并运行尽可能多的进程
pm2 start app.js -i max
# 通过配置文件启动
module.exports = {
apps : [{
script : "app.js",
instances : "max",
exec_mode : "cluster"
}]
}
# 注意:pm2 的负载均衡的特性是建立在以集群模式启动的基础上的,默认的启动模式是 fork,不支持负载均衡
# 集群模式下,由于 pm2 的 restart 命令会先杀掉所有进程,再重新拉起,会造成服务终止。
# 但是 reload 命令可以实现 0s 重启,维护升级的时候不需要停机。当重载时间过长或者无法重载时,pm2 会自动切换成 restart
pm2 reload app.js #重新启动所有进程,始终保持至少一个进程在运行
pm2 gracefulReload all #优雅地以群集模式重新加载所有应用程序
**-i
**后面的数字说明
# 如果希望在运行中动态增加实例数,可以使用下面的命令
pm2 scale <app_name> +4 # add 4 additional workers in realtime
# 只要通过PM2 启动的Node.js项目,可以非常方便的查看其输出日志
# 显示所有应用的实时日志
pm2 logs
# 显示 api 应用的日志
pm2 logs api
# json格式显示所有应用的日志
pm2 logs --json
# 显示1000行 big-api 的日志
pm2 logs big-api --lines 1000
# 用仪表盘显示所有应用
pm2 monit
# 输出日志加上时间
pm2 start app.js --time
pm2 restart app --time
# 默认日志的路径
HOME/.pm2/logs
# 查看日志命令的可用选项
pm2 logs -h
# 启动应用时,怎么初始化日志相关信息
pm2 start app.js [OPTIONS]
-l --log [path] specify filepath to output both out and error logs
-o --output <path> specify out log file
-e --error <path> specify error log file
--time prefix logs with standard formated timestamp
--log-date-format <format> prefix logs with custom formated timestamp
--merge-logs 适用 cluster mode
# cluster mode 中,让所有进程日志都写进同一个日志
# 命令启动,加上选项
pm2 start app.js -i max --merge-logs <具体日志文件>
# 配置文件中,设置属性:
merge_logs: true
# 不需要输出日志
module.exports = {
apps: [{
name: 'Business News Watcher',
script: 'app.js',
instances: 1,
out_file: "/dev/null",
error_file: "/dev/null",
cron_restart: '0 0 * * *',
[...]
}]
}
# 清除所有应用的日志
pm2 flush
# 清除 api 应用的日志
pm2 flush <api>
# 日志文件的大小,以及日志保存多久等功能需要额外插件支持:
pm2 install pm2-logrotate
# 监控项目目录下所有文件,任意文件有改动,就自动重启 node.js 项目
# 用 pm2 启动 node.js 项目,项目目录下有文件改动就重启
pm2 start app.js --watch
# 现在就可以正常访问 node.js 项目了,且可以查看项目状态
pm2 list
pm2 log
# --ignore-watch 可以去除一些不需要监控的目录或文件
# 监控除了 node_modules 目录以外文件
pm2 start app.js --watch --ignore-watch="node_modules"
# 配置文件中设置监控的方法
# 监控和忽略具体文件
module.exports = {
script: "app.js",
// 监控这两个文件夹
watch: ["server", "client"],
// 监控时间间隔
watch_delay: 1000,
// 忽略这两个文件夹
ignore_watch: ["node_modules", "client/img"],
}
# 监控项目目录下所有文件
module.exports = {
script: "app.js",
watch: true
}
# --------------------------restart 与 reload 区别-----------
# restart 会杀掉现有进程 并 启动新进程,服务会中断;
# reload 不会杀掉现有进程,在现有进程重新加载,服务不会中断
# 只有 app_name 这个应用被reload
pm2 reload <app_name>
# 配置文件中所有应用都被reload
pm2 reload process.json
# 只有配置文件中的api应用被reload
pm2 reload process.json --only api
# 当服务器意外崩溃重启后,Node.js要能够自启动,恢复服务
# 1、创建启动脚本
pm2 startup
# 2、上面命令会输出类似如下提示,按照提示执行
[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/local/nodejs/bin /usr/local/nodejs/lib/node_modules/pm2/bin/pm2 startup systemd -u shawn --hp /home/shawn
# 3、保存正在运行的应用到启动脚本
pm2 save
# 现在可以重启服务器,看看 node.js 项目是否能自启动
# 恢复上一次保存的自启动列表
pm2 resurrect
# 取消自启动
pm2 unstartup
# 当 node.js 版本更新时,请一定要卸载并新建 自启动脚本
pm2 unstartup
pm2 startup
# 如果我们还希望PM2中的进程能随着PM2启动而启动,就需要每次在新增或删除进程后执行pm2 save
# 自动加入重启
# 我们对进程的变更将会被即时保存到~/.pm2/dump.pm2中,无需手动执行pm2 save
pm2 set pm2:autodump true
# 生成配置文件,pm2 init simple
# 生成默认配置文件:ecosystem.config.js
module.exports = {
apps : [{
name : "app1",
script : "./app.js"
}]
}
# 添加环境变量配置
module.exports = {
apps: [{
name: "app1",
script: "./app.js",
env: {
"ip": "192.168.1.2",
"NODE_ENV": "development"
},
env_production: {
"ip": "192.168.1.1",
"NODE_ENV": "production",
}
env_develop: {
"ip": "192.168.1.2",
"NODE_ENV": "develop",
}
}]
}
调用环境变量
env
默认环境变量,只要启动应用:pm2 start ecosystem.config.js
,那么 ip 变量就会被传递给应用 app1env_production
对应调用方式是:pm2 start ecosystem.config.js --env production
env_develop
对应调用方式是:pm2 start ecosystem.config.js --env develop
env_
开头的属性,那么就用 --env
参数调用。--update-env
: 更新环境变量
NODE_ENV=production pm2 restart web-interface --update-env
在 node.js 项目部署发布时,经常用 SSH 分别连接多台服务器,对每一台服务器都要执行 git pull 最新代码,编译启动应用的操作,操作琐碎且容易忘记其中某些操作。pm2 可以很好解决这个问题,只需一个命令就可以自动完成,还能实时监控、查看 node.js 应用的运行情况
第一步:服务器环境配置
npm install pm2@latest -g
或 yarn global add pm2
git clone
,不会,看这里!第二步:开发机器环境配置
// node.js 项目操作步骤配置,注意修改对应的信息
// pm2 init 等同于 pm2 ecosystem,可以生成带有 deploy 属性的配置文件:ecosystem.config.js
module.exports = {
apps : [{
name : 'API', //应用名
script : 'app.js', //应用文件位置
env: {
PM2_SERVE_PATH: ".", //静态服务路径
PM2_SERVE_PORT: 8080, //静态服务器访问端口
NODE_ENV: 'development' //启动默认模式
},
env_production : {
NODE_ENV: 'production' //使用production模式 pm2 start ecosystem.config.js --env production
},
instances:"max", //将应用程序分布在所有CPU核心上,可以是整数或负数
watch:true, //监听模式
output: './out.log', //指定日志标准输出文件及位置
error: './error.log', //错误输出日志文件及位置,pm2 install pm2-logrotate进行日志文件拆分
merge_logs: true, //集群情况下,可以合并日志
log_type:"json", //日志类型
log_date_format: "DD-MM-YYYY", //日志日期记录格式
}],
deploy : {
production : {
user : 'node', //ssh 用户
host : ["192.168.0.13", "192.168.0.14", "192.168.0.15"], //ssh 地址
ref : 'origin/master', //GIT远程/分支
repo : 'git@github.com:repo.git', //git地址
path : '/var/www/production', //服务器文件路径
post-deploy : 'npm install && pm2 reload ecosystem.config.js --env production' //部署后的动作
}
}
};
最后执行命令
# pm2 连接服务器,通知其 git clone 代码等初始化工作
pm2 deploy production setup
# 启动 或 更新 node.js 项目
# 让服务器 git pull 代码,编译后启动应用
# --force 的作用:如果服务器本地代码有改动,那么放弃改动,用git仓库最新代码更新项目
pm2 deploy production --force;
下面说一下命令详解
# 命令格式
# 如果配置文件名是:ecosystem.config.js或者 pm2.config.js,上面命令可以不用写 <configuration_file>
pm2 deploy <configuration_file> <environment> <command>
# 此命令就是默认寻找 ecosystem.config.js 或 pm2.config.js 配置文件执行
pm2 deploy production setup
# 在配置文件中设定 env_production和 env_development,就可以在执行命令时调用,把环境变量传递给node.js 项目
# pm2 deploy production --force;
module.exports = {
apps: [{
script: 'index.js',
watch: '.',
env_production: {
NODE_ENV: "production"
},
env_development: {
NODE_ENV: "development"
}
}],
}
# command
setup run remote setup commands
update update deploy to the latest release
revert[n] revert to[n]th last deployment or 1
curr[ent] output current release commit
prev[ious] output previous release commit
exec | run < cmd > execute the given < cmd >
list list previous deploy commits
[ref] deploy to[ref], the "ref" setting, or latest tag
# exec可以让所有服务器执行一次命令
pm2 deploy production exec "pm2 reload all"
# 回滚到上一个部署版本
pm2 deploy production revert 1
# 部署的几个时间点
"pre-setup" : "在setup执行前 运行的 命令或脚本",
"post-setup" : "在代码clone完成后 执行的命令或脚本",
"pre-deploy" : "pm2 startOrRestart ecosystem.json --env production",
"post-deploy" : "pm2 startOrRestart ecosystem.json --env production",
"pre-deploy-local" : "echo 'This is a local executed command'"
# 操作多台服务器,只需修改host,单台就一个
"host" : ["212.83.163.1", "212.83.163.2", "212.83.163.3"],
# -------------------------------报错解决---------------------------
npm: command not found
post-deploy hook failed
Deploy failed
# pm2 部署时,出现上面错误,但运行 npm -v都是正常的,原因是 pm2 的配置文件,按照下面步骤即可解
# 1、打开终端
$ cd ~
$ nano .bashrc
# 2、把下面内容注释掉
#If not running interactively, don 't do anything
case $ - in
*
i * );;
*) return;;
esac
# 3、更新环境变量
$ source .bashrc
# --------------------------------1---------------------------
# 假设 ~/test目录下有一个 test.txt文件
# 开启文件服务器,默认端口是8080,可以根据需要修改
pm2 serve ~/test 8080
# 浏览器访问
http://localhost:8080/test.txt
# --------------------------------2---------------------------
# 假设 ~/test目录下有一个 test.txt文件
# 1、切换到共享目录
cd ~/test
# 2、新建配置文件 : ecosystem.config.js
pm2 init simple
# 3、修改配置文件为如下内容
module.exports = {
apps: [{
name: "serve",
script: "serve",
env: {
PM2_SERVE_PATH: '.',
PM2_SERVE_PORT: 8080
}
}]
}
# 4、启动服务
pm2 start ecosystem.config.js
#或者
pm2 start
# 5、浏览器访问
http://localhost:8080/test.txt
# --------------------------------3---------------------------
# 假设共享目录有index.html 文件,文件内容如下。访问共享目录时,默认打开 index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>pm2 serve</title>
</head>
<body>
<h1>Welcome</h1>
<p>这是 pm2 服务器!</p>
</body>
</html>
# ---------命令行启动
# 1、切换到共享目录
cd ~/test
# 2、启动服务
pm2 serve --spa
# 3、访问
http://localhost:8080
# ---------配置文件启动
# 1、切换到共享目录
cd ~/test
# 2、新建配置文件 : ecosystem.config.js
pm2 init simple
# 3、修改配置文件为如下内容
module.exports = {
apps: [{
name: "serve",
script: "serve",
env: {
PM2_SERVE_PATH: '.',
PM2_SERVE_PORT: 8080,
PM2_SERVE_SPA: 'true'
}
}]
}
# 4、启动服务
pm2 start ecosystem.config.js
#或者
pm2 start
# 5、浏览器访问
http://localhost:8080
# --------------------------------4---------------------------
# 使用用户名和密码来访问服务
# --------------命令行启动
# 1、切换到共享目录
cd ~/test
# 2、启动服务,用户名:username,密码:password
pm2 serve --basic-auth-username username --basic-auth-password password
# 3、浏览器访问(需要输入上面用户名和密码)
http://localhost:8080
# --------------配置文件启动
# 1、切换到共享目录
cd ~/test
# 2、新建配置文件 : ecosystem.config.js
pm2 init simple
# 3、修改配置文件为如下内容
module.exports = {
apps: [{
name: "serve",
script: "serve",
env: {
PM2_SERVE_PATH: '.',
PM2_SERVE_PORT: 8080,
PM2_SERVE_BASIC_AUTH: 'true',
PM2_SERVE_BASIC_AUTH_USERNAME: 'username',
PM2_SERVE_BASIC_AUTH_PASSWORD: 'password'
}
}]
}
# 4、启动服务
pm2 start ecosystem.config.js
#或者
pm2 start
# 5、浏览器访问(需要输入上面用户名和密码)
http://localhost:8080
Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启,这是另一种监控后台的方式,详情可以参考:Supervisor+Dockerfile编译jdk镜像
#在容器中安装 pm2
RUN npm install pm2 -g
# 直接启动应用
CMD ["pm2-runtime", "app.js"]
# 通过配置文件启动
CMD ["pm2-runtime", "ecosystem.config.js"]
**注意:在容器中使用 pm2 启动应用时,要使用 pm2-runtime
而不是 pm2 start
, 因为:**pm2 是默认后台启动的, docker 感知不到。CMD 命令执行完成,docker 容器就结束了。 所以直接使用 node app.js
启动应用后,应用能一直在容器中保持运行。 pm2 以后台形式运行,CMD 命令执行完成,docker 就认为可以退出了。所以需要使用 pm2-runtime
来进行处理。pm2-runtime
是为 Docker 容器设计的,它将应用程序置于前台,从而使容器保持运行状态
https://pm2.keymetrics.io/docs/usage/quick-start/
https://www.jianshu.com/p/02af8c5261e5