一、PM2概述
1、簡(jiǎn)介
進(jìn)程管理主要是指創(chuàng)建,終止和監(jiān)控進(jìn)程。進(jìn)程管理器主要是用來(lái)確保你的應(yīng)用在啟動(dòng)后能夠保持在線
pm2 是 nodejs 的進(jìn)程管理器,默認(rèn)支持負(fù)載均衡,能夠守護(hù)進(jìn)程。還支持查看應(yīng)用運(yùn)行時(shí)的性能,資源占用情況等
2、普通 node 進(jìn)程的缺陷
- 普通啟動(dòng)方式:node index.js,關(guān)閉終端就結(jié)束進(jìn)程
- node 進(jìn)程掛掉和“僵死”:
- 進(jìn)程掛掉大概有以下幾種原因:
- 內(nèi)存泄漏:內(nèi)存一點(diǎn)點(diǎn)積累到達(dá)臨界值爆掉
- 死循環(huán)導(dǎo)致內(nèi)存突增爆掉
- 死循環(huán)導(dǎo)致磁盤寫爆
- 被動(dòng)被kill,主動(dòng)退出。
- “僵死”大概有以下幾種可能:
- 有某個(gè)非常耗時(shí)的cpu操作正在執(zhí)行
- 寫了個(gè)死循環(huán)(死循環(huán)不一定會(huì)導(dǎo)致服務(wù)掛掉,有可能只會(huì)cpu飆升,讓服務(wù)處于假死狀態(tài))
- 進(jìn)程掛掉大概有以下幾種原因:
不管發(fā)生上面哪種情況,都會(huì)造成服務(wù)的不可訪問(wèn),需要等我們自己去發(fā)現(xiàn)問(wèn)題后,然后重啟應(yīng)用。
3、PM2優(yōu)點(diǎn)
- 后臺(tái)運(yùn)行:普通啟動(dòng)方式:node index.js,關(guān)閉終端就結(jié)束進(jìn)程;pm2可以后臺(tái)運(yùn)行,終端關(guān)閉不影響
- 自動(dòng)重啟:在應(yīng)用意外掛掉或者機(jī)器重啟后,能夠自動(dòng)重啟應(yīng)用;可以監(jiān)聽某些文件改動(dòng),自動(dòng)重啟
- 停止不穩(wěn)定的進(jìn)程:限制不穩(wěn)定的重啟的次數(shù),達(dá)到上限就停止進(jìn)程
- 自動(dòng)負(fù)載均衡:支持集群模式,會(huì)自動(dòng)使用輪詢的方式達(dá)到負(fù)載均衡,可以方便的啟動(dòng)多個(gè)node進(jìn)程,充分利用cpu和內(nèi)存
- 0 秒停機(jī)重啟:集群模式下,可以達(dá)到重啟時(shí)不停止服務(wù)
- 簡(jiǎn)單日志管理:pm2可以收集日志,并有插件配合進(jìn)行管理
- 提供實(shí)時(shí)的接口:pm2插件提供實(shí)時(shí)的接口,返回服務(wù)器與進(jìn)程的信息
- 可以監(jiān)控應(yīng)用性能,資源占用情況等,自動(dòng)輸出日志
- 開發(fā)模式支持熱更新
- 集成管理:對(duì)于多個(gè)進(jìn)程,不同環(huán)境,可以統(tǒng)一配置,方便管理
4、PM2安裝
# 沒(méi)有nodejs的需要首先安裝
# 安裝地址http://nodejs.cn/download/
# 有問(wèn)題
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命令詳情
1、PM2常用命令
快速入門:https://pm2.keymetrics.io/docs/usage/quick-start/
1.1 啟動(dòng)
# pm2有兩種模式,開發(fā)模式和生產(chǎn)模式
# 開發(fā) node 應(yīng)用的時(shí)候,修改代碼過(guò)后每次都要重啟下應(yīng)用,很麻煩。使用 pm2-dev 命令啟動(dòng)應(yīng)用,應(yīng)用會(huì)在在代碼發(fā)生變更過(guò)后,自動(dòng)重啟
pm2-dev start server.js
# 應(yīng)用部署到生產(chǎn)環(huán)境后,可以使用 pm2 start 來(lái)啟動(dòng)應(yīng)用,命令啟動(dòng)的應(yīng)用,默認(rèn)支持進(jìn)程守護(hù),并且可以通過(guò) pm2 進(jìn)行監(jiān)控
pm2 start server.js
# 啟動(dòng)指定應(yīng)用,如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
# 設(shè)置啟動(dòng)應(yīng)用的顯示名稱
pm2 start app.js --name <app_name>
# 監(jiān)控應(yīng)用目錄,一旦有文件發(fā)生更改就立刻重啟應(yīng)用
pm2 start app.js --watch
# 指定日志輸出目錄
pm2 start app.js --log <log_path>
# 設(shè)置應(yīng)用重啟時(shí),能使用內(nèi)存的最大值
pm2 start app.js --max-memory-restart <200MB>
# 啟動(dòng)時(shí),傳遞參數(shù)給 app 應(yīng)用
pm2 start app.js -- arg1 arg2 arg3
# 禁止自動(dòng)重啟應(yīng)用
pm2 start app.js --no-autorestart
# 定時(shí)任務(wù)。可以設(shè)置 一天中的固定重啟時(shí)間, 一周內(nèi)固定重啟日期,或者 一個(gè)時(shí)間間隔(如 每 48 小時(shí)重啟一次)
# cron_pattern參考:https://www.npmjs.com/package/cron
pm2 start app.js --cron <cron_pattern>
# 固定延時(shí)重啟,這里的2000單位為毫秒,即在需要重啟的時(shí)候等待兩秒鐘
pm2 start --restart-delay=2000
# 靈活延時(shí),重試時(shí)間會(huì)隨著重試次數(shù)增多不斷延長(zhǎng)
# 此處的1000單位也是毫秒,PM2會(huì)在多次重啟失敗后以設(shè)定的時(shí)間為初始值,使用指數(shù)移動(dòng)平均算法不斷延長(zhǎng)重試時(shí)間,最高為15000毫秒(即15秒),并在進(jìn)程成功啟動(dòng)30秒后重置重試時(shí)間到到初始值
pm2 start --exp-backoff-restart-delay=1000
# 靜態(tài)服務(wù)器,將目錄dist作為靜態(tài)服務(wù)器根目錄,端口為9090
pm2 serve ./dist 9090
1.2 管理進(jìn)程
app_name
的位置除了傳應(yīng)用名,還可以傳:
-
all
針對(duì)所有進(jìn)程進(jìn)行操作 -
id
針對(duì)特定id的進(jìn)程進(jìn)行操作
集群模式下,restart中斷服務(wù),而reload不會(huì)
# ------------------------------重啟、重載、停止、刪除------------------------
# 停止指定應(yīng)用,如pm2 stop httpServer;
# 也可以執(zhí)行他目錄下得 pm2-start.sh 腳本里面用. pm2-start.sh 執(zhí)行輸入0就可以關(guān)閉在執(zhí)行得腳本
# (app_name|app_id|all)
pm2 stop [options]
# 重啟指定應(yīng)用,如pm2 restart httpServer;
pm2 reload|restart [options]
# 顯示指定應(yīng)用詳情,如pm2 show httpServer;
pm2 show [options]
# 刪除指定應(yīng)用,如pm2 delete httpServer,如果修改應(yīng)用配置行為,最好先刪除應(yīng)用后,重新啟動(dòng)方才生效,如修改腳本入口文件;
pm2 delete [options]
# 重置 restart 的計(jì)時(shí)器
pm2 reset all
# 殺掉pm2管理的所有進(jìn)程;
pm2 kill
# 保存并恢復(fù)PM2進(jìn)程
pm2 update
1.3 應(yīng)用信息查看
#----------------------------查看運(yùn)行狀態(tài)-------------------------
# 查看所有進(jìn)程信息(app_name、app_id等)
pm2 [list|ls|status]
# 對(duì)應(yīng)用進(jìn)行排序查看
pm2 list --sort name:desc
# Or
pm2 list --sort [name|id|pid|memory|cpu|status|uptime][:asc|desc]
# 查看某個(gè)應(yīng)用詳情
pm2 describe app_name|app_id
# 查看應(yīng)用詳情信息
pm2 show app_name|app_id
# 清除保存的應(yīng)用列表
pm2 cleardump
# 保存當(dāng)前應(yīng)用列表,以后可以恢復(fù)
pm2 save # 同 pm2 dump
# 重新加載之前保存的應(yīng)用列表
pm2 resurrect
運(yùn)行pm2 list
的命令后,可以查看所有 pm2 啟動(dòng)的應(yīng)用
-
id
:應(yīng)用 id -
name
:應(yīng)用名稱 -
namespace
:在配置文件里面可以給應(yīng)用設(shè)置 namespace。設(shè)置后可以使用命令行單獨(dú)啟動(dòng)或停止某個(gè) namespace 的應(yīng)用 -
mode
: 進(jìn)程的運(yùn)行方式。分為fork
與cluster
-
pid
:進(jìn)程id -
uptime
:運(yùn)行時(shí)間 -
?
:重啟次數(shù)(從0開始計(jì)數(shù)) -
status
:進(jìn)程是否在線 -
cpu
:cpu占用率 -
mem
:內(nèi)存占用大小
而pm2 show app_name|app_id
查看應(yīng)用詳情信息,除了 pm2 list
命令返回的信息以外,還可以獲取幾個(gè)常用信息
-
script path
:?jiǎn)?dòng)入口的文件路徑 -
script args
:?jiǎn)?dòng)文件的參數(shù) -
error log path
:錯(cuò)誤日志的文件路徑 -
out log path
:輸出日志的文件路徑 -
exec mode
:進(jìn)程的模式 -
watch&reload
:是否開啟監(jiān)聽文件變動(dòng)重啟 -
unstable restarts
:不穩(wěn)定的重啟次數(shù)
1.4 日志與監(jiān)控
# 查看指定應(yīng)用的日志,即標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤;
pm2 logs [options] [id|name|namespace]
pm2 logs
# 還可以直接進(jìn)入日志保存的目錄查看
# 監(jiān)控各個(gè)應(yīng)用進(jìn)程cpu和memory使用情況
pm2 monit
# 查看所有命令
pm2 --help
#or
pm2 -h
2、集成部署EcosystemFile
官方參考:https://pm2.keymetrics.io/docs/usage/application-declaration/
2.1 概述
當(dāng)我們需要管理多個(gè)應(yīng)用,或者應(yīng)用有多個(gè)運(yùn)行環(huán)境時(shí),使用 pm2 start
來(lái)啟動(dòng)應(yīng)用+配置參數(shù)是很不方便的。所以,pm2 支持使用配置文件來(lái)啟動(dòng)和管理應(yīng)用。
# 生成配置文件
pm2 init simple
# 運(yùn)行該命令可在工程下初始化一個(gè) ecosystem.config.js 配置文件
module.exports = {
apps : [{
name : "app1",
script : "./app.js"
}]
}
# apps是要管理應(yīng)用的數(shù)組,每個(gè)對(duì)象都是一個(gè)應(yīng)用的配置
# 你也可以自己創(chuàng)建一個(gè)配置文件,文件名以 .config.js 結(jié)尾,pm2 會(huì)自動(dòng)識(shí)別并讀取該文件
# 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
2.2 配置項(xiàng)詳解
基礎(chǔ)配置
- name:進(jìn)程名
- script:node 啟動(dòng)文件的路徑
- cwd :項(xiàng)目所在的目錄
- args :通過(guò)命令行傳遞給node啟動(dòng)文件的參數(shù)
- interpreter :編譯器的絕對(duì)路徑(默認(rèn) node )
- interpreter_args :傳給編譯器的參數(shù)
- node_args:傳給 node 的參數(shù)
進(jìn)階配置
- instances :應(yīng)用啟動(dòng)實(shí)例個(gè)數(shù),僅在cluster模式有效
- exec_mode :應(yīng)用程序啟動(dòng)模式??蛇x
cluster
或fork
,默認(rèn)為fork
- watch :是否啟用監(jiān)控模式,默認(rèn)是
false
。如果設(shè)置成true
,當(dāng)應(yīng)用程序變動(dòng)時(shí),pm2會(huì)自動(dòng)重載 - ignore_watch :不用監(jiān)聽的文件,如
ignore_watch: [
'node_modules',
'logs',
]
-
max_memory_restart :應(yīng)用運(yùn)行內(nèi)存達(dá)到設(shè)定值后,會(huì)自動(dòng)重啟。避免了
Node.js heap out of memory error
問(wèn)題 -
env :應(yīng)用中的默認(rèn)環(huán)境變量
-
env_ :命令行中可傳入的環(huán)境變量,覆蓋默認(rèn)環(huán)境變量
-
source_map_support :默認(rèn)
true
,支持 sourcemap 文件
日志配置
- log_date_format :日志時(shí)間格式
- error_file :錯(cuò)誤日志存放路徑
- out_file :全部日志存放路徑
- combine_logs:是否將不同 id 的進(jìn)程日志合并
- merge_logs:同上
控制流
- min_uptime:應(yīng)用被視為已啟動(dòng)最小運(yùn)行時(shí)間
- max_restarts: 在應(yīng)用狀態(tài)被認(rèn)定為
error
前,一定時(shí)間(min_uptime
指定的時(shí)間,若未配置,則為 1 秒)內(nèi)的連續(xù)不穩(wěn)定重啟次數(shù)
# 以上兩個(gè)配置項(xiàng)一般需要同時(shí)設(shè)置,以下舉個(gè)例子
# 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 應(yīng)用在啟動(dòng) 1s 后,會(huì)自己強(qiáng)行結(jié)束進(jìn)程。這時(shí), pm2 由于進(jìn)程守護(hù)的特性,會(huì)去重新拉起應(yīng)用。
# 示例中設(shè)置了 min_uptime 為 5000(即 5s),max_restarts 為 4 次,所以 pm2 在進(jìn)程停止(1s)后去重啟進(jìn)程,5s 鐘可以內(nèi)重啟次數(shù)肯定可以達(dá)到 4 次。達(dá)到設(shè)定次數(shù)后,則停止重啟應(yīng)用
- listen_timeout:如果應(yīng)用沒(méi)有發(fā)送
ready
信號(hào),間隔多長(zhǎng)時(shí)間 reload。單位為毫秒。 - wait_ready:是否等待進(jìn)程發(fā)送
ready
信號(hào)。默認(rèn)為false
。設(shè)置為true
后,需要在應(yīng)用內(nèi)部添加process.send('ready')
語(yǔ)句發(fā)送ready
信號(hào)。
以上兩個(gè)配置項(xiàng)一般需要搭配使用,詳細(xì)使用場(chǎng)景見 優(yōu)雅的啟動(dòng)與停止應(yīng)用
- kill_timeout:從告訴進(jìn)程要關(guān)閉到強(qiáng)制關(guān)閉進(jìn)程的間隔時(shí)間。
module.exports = {
apps : [{
name: 'app',
script: './app.js',
kill_timeout: 3000
}]
}
當(dāng) pm2 要停止或重啟一個(gè)應(yīng)用時(shí),會(huì)按順序給你的進(jìn)程發(fā)送一系列系統(tǒng)信號(hào)。它首先會(huì)發(fā)送一個(gè) SIGINT
信號(hào)告訴你應(yīng)用將會(huì)被停止。然后 pm2 會(huì)等待 3s(示例中 kill_timeout
設(shè)置的時(shí)間)。若 3s 后應(yīng)用沒(méi)有自己停止(exit),pm2 會(huì)發(fā)送一個(gè) SIGKILL
信號(hào)來(lái)強(qiáng)制停止應(yīng)用。優(yōu)雅停止
- estart_delay:進(jìn)程掉線后,等待多長(zhǎng)時(shí)間自動(dòng)重啟, 默認(rèn) 0s
- autorestart: 是否開啟自動(dòng)重啟。默認(rèn)開啟。
- cron_restart: 定時(shí)重啟??梢栽O(shè)置 一天中的固定重啟時(shí)間, 一周內(nèi)固定重啟日期,或者 一個(gè)時(shí)間間隔(如 每 48 小時(shí)重啟一次)。cron_pattern 請(qǐng)參照這里
2.3 使用配置文件
# 啟動(dòng)、停止、重啟、重載、刪除配置文件中所有項(xiàng)目
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
# 啟動(dòng)指定應(yīng)用
pm2 start ecosystem.config.js --only api-app
pm2 start ecosystem.config.js --only "api-app,worker-app"
3、集群模式
https://pm2.keymetrics.io/docs/usage/cluster-mode/
3.1 cluster 模式與 fork 模式
- fork 模式 :fork 模式使用最基本的進(jìn)程運(yùn)行方式,只是單實(shí)例運(yùn)行server,無(wú)法實(shí)現(xiàn) TCP 連接共享。并且我們知道 JavaScript 代碼是運(yùn)行在單線程上的,換句話說(shuō)一個(gè) Node.js 進(jìn)程只能運(yùn)行在一個(gè) CPU 上。那么如果用 Node.js 來(lái)做 Web Server,就無(wú)法享受到多核運(yùn)算的好處
- cluster 模式:集群模式允許 nodejs 應(yīng)用程序在所有可用的 CPU 上進(jìn)行擴(kuò)展,而無(wú)需修改任何代碼。可以顯著提高應(yīng)用程序的性能和可靠性,具體取決于可用的 CPU 數(shù)量。在底層,它使用了 Node.js 集群模塊,這樣擴(kuò)展后的應(yīng)用程序的子進(jìn)程可以自動(dòng)共享服務(wù)器端口。要了解更多信息,請(qǐng)參閱 Node.js 集群
3.2 集群的使用
# 命令行啟動(dòng)
# max 的意思是:把應(yīng)用部署到服務(wù)器所有可用的CPU上,并運(yùn)行盡可能多的進(jìn)程
pm2 start app.js -i max
# 通過(guò)配置文件啟動(dòng)
module.exports = {
apps : [{
script : "app.js",
instances : "max",
exec_mode : "cluster"
}]
}
# 注意:pm2 的負(fù)載均衡的特性是建立在以集群模式啟動(dòng)的基礎(chǔ)上的,默認(rèn)的啟動(dòng)模式是 fork,不支持負(fù)載均衡
# 集群模式下,由于 pm2 的 restart 命令會(huì)先殺掉所有進(jìn)程,再重新拉起,會(huì)造成服務(wù)終止。
# 但是 reload 命令可以實(shí)現(xiàn) 0s 重啟,維護(hù)升級(jí)的時(shí)候不需要停機(jī)。當(dāng)重載時(shí)間過(guò)長(zhǎng)或者無(wú)法重載時(shí),pm2 會(huì)自動(dòng)切換成 restart
pm2 reload app.js #重新啟動(dòng)所有進(jìn)程,始終保持至少一個(gè)進(jìn)程在運(yùn)行
pm2 gracefulReload all #優(yōu)雅地以群集模式重新加載所有應(yīng)用程序
**-i
**后面的數(shù)字說(shuō)明
- 0/max :開啟進(jìn)程數(shù)量 == cpu核數(shù)量
- -1:進(jìn)程數(shù)量 == cpu核數(shù)量 - 1
3.3 動(dòng)態(tài)擴(kuò)展
# 如果希望在運(yùn)行中動(dòng)態(tài)增加實(shí)例數(shù),可以使用下面的命令
pm2 scale <app_name> +4 # add 4 additional workers in realtime
4、PM2其他進(jìn)階
4.1 日志輸出
https://pm2.keymetrics.io/docs/usage/log-management/
# 只要通過(guò)PM2 啟動(dòng)的Node.js項(xiàng)目,可以非常方便的查看其輸出日志
# 顯示所有應(yīng)用的實(shí)時(shí)日志
pm2 logs
# 顯示 api 應(yīng)用的日志
pm2 logs api
# json格式顯示所有應(yīng)用的日志
pm2 logs --json
# 顯示1000行 big-api 的日志
pm2 logs big-api --lines 1000
# 用儀表盤顯示所有應(yīng)用
pm2 monit
# 輸出日志加上時(shí)間
pm2 start app.js --time
pm2 restart app --time
# 默認(rèn)日志的路徑
HOME/.pm2/logs
# 查看日志命令的可用選項(xiàng)
pm2 logs -h
# 啟動(dòng)應(yīng)用時(shí),怎么初始化日志相關(guān)信息
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 中,讓所有進(jìn)程日志都寫進(jìn)同一個(gè)日志
# 命令啟動(dòng),加上選項(xiàng)
pm2 start app.js -i max --merge-logs <具體日志文件>
# 配置文件中,設(shè)置屬性:
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 * * *',
[...]
}]
}
# 清除所有應(yīng)用的日志
pm2 flush
# 清除 api 應(yīng)用的日志
pm2 flush <api>
# 日志文件的大小,以及日志保存多久等功能需要額外插件支持:
pm2 install pm2-logrotate
4.2 監(jiān)控模式實(shí)時(shí)更新
https://pm2.keymetrics.io/docs/usage/restart-strategies/
# 監(jiān)控項(xiàng)目目錄下所有文件,任意文件有改動(dòng),就自動(dòng)重啟 node.js 項(xiàng)目
# 用 pm2 啟動(dòng) node.js 項(xiàng)目,項(xiàng)目目錄下有文件改動(dòng)就重啟
pm2 start app.js --watch
# 現(xiàn)在就可以正常訪問(wèn) node.js 項(xiàng)目了,且可以查看項(xiàng)目狀態(tài)
pm2 list
pm2 log
# --ignore-watch 可以去除一些不需要監(jiān)控的目錄或文件
# 監(jiān)控除了 node_modules 目錄以外文件
pm2 start app.js --watch --ignore-watch="node_modules"
# 配置文件中設(shè)置監(jiān)控的方法
# 監(jiān)控和忽略具體文件
module.exports = {
script: "app.js",
// 監(jiān)控這兩個(gè)文件夾
watch: ["server", "client"],
// 監(jiān)控時(shí)間間隔
watch_delay: 1000,
// 忽略這兩個(gè)文件夾
ignore_watch: ["node_modules", "client/img"],
}
# 監(jiān)控項(xiàng)目目錄下所有文件
module.exports = {
script: "app.js",
watch: true
}
# --------------------------restart 與 reload 區(qū)別-----------
# restart 會(huì)殺掉現(xiàn)有進(jìn)程 并 啟動(dòng)新進(jìn)程,服務(wù)會(huì)中斷;
# reload 不會(huì)殺掉現(xiàn)有進(jìn)程,在現(xiàn)有進(jìn)程重新加載,服務(wù)不會(huì)中斷
# 只有 app_name 這個(gè)應(yīng)用被reload
pm2 reload <app_name>
# 配置文件中所有應(yīng)用都被reload
pm2 reload process.json
# 只有配置文件中的api應(yīng)用被reload
pm2 reload process.json --only api
4.3 PM2自啟動(dòng)
https://pm2.keymetrics.io/docs/usage/startup/
# 當(dāng)服務(wù)器意外崩潰重啟后,Node.js要能夠自啟動(dòng),恢復(fù)服務(wù)
# 1、創(chuàng)建啟動(dòng)腳本
pm2 startup
# 2、上面命令會(huì)輸出類似如下提示,按照提示執(zhí)行
[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、保存正在運(yùn)行的應(yīng)用到啟動(dòng)腳本
pm2 save
# 現(xiàn)在可以重啟服務(wù)器,看看 node.js 項(xiàng)目是否能自啟動(dòng)
# 恢復(fù)上一次保存的自啟動(dòng)列表
pm2 resurrect
# 取消自啟動(dòng)
pm2 unstartup
# 當(dāng) node.js 版本更新時(shí),請(qǐng)一定要卸載并新建 自啟動(dòng)腳本
pm2 unstartup
pm2 startup
# 如果我們還希望PM2中的進(jìn)程能隨著PM2啟動(dòng)而啟動(dòng),就需要每次在新增或刪除進(jìn)程后執(zhí)行pm2 save
# 自動(dòng)加入重啟
# 我們對(duì)進(jìn)程的變更將會(huì)被即時(shí)保存到~/.pm2/dump.pm2中,無(wú)需手動(dòng)執(zhí)行pm2 save
pm2 set pm2:autodump true
4.4 環(huán)境變量隔離
https://pm2.keymetrics.io/docs/usage/environment/
# 生成配置文件,pm2 init simple
# 生成默認(rèn)配置文件:ecosystem.config.js
module.exports = {
apps : [{
name : "app1",
script : "./app.js"
}]
}
# 添加環(huán)境變量配置
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",
}
}]
}
調(diào)用環(huán)境變量
-
env
默認(rèn)環(huán)境變量,只要啟動(dòng)應(yīng)用:pm2 start ecosystem.config.js
,那么 ip 變量就會(huì)被傳遞給應(yīng)用 app1 -
env_production
對(duì)應(yīng)調(diào)用方式是:pm2 start ecosystem.config.js --env production
-
env_develop
對(duì)應(yīng)調(diào)用方式是:pm2 start ecosystem.config.js --env develop
- 規(guī)則是 :配置文件中定義
env_
開頭的屬性,那么就用--env
參數(shù)調(diào)用。
--update-env
: 更新環(huán)境變量
NODE_ENV=production pm2 restart web-interface --update-env
4.5 多服務(wù)器管理
https://pm2.keymetrics.io/docs/usage/deployment/
在 node.js 項(xiàng)目部署發(fā)布時(shí),經(jīng)常用 SSH 分別連接多臺(tái)服務(wù)器,對(duì)每一臺(tái)服務(wù)器都要執(zhí)行 git pull 最新代碼,編譯啟動(dòng)應(yīng)用的操作,操作瑣碎且容易忘記其中某些操作。pm2 可以很好解決這個(gè)問(wèn)題,只需一個(gè)命令就可以自動(dòng)完成,還能實(shí)時(shí)監(jiān)控、查看 node.js 應(yīng)用的運(yùn)行情況
第一步:服務(wù)器環(huán)境配置
- 安裝 node.js :不會(huì),看這里!
- 安裝 pm2 :
npm install pm2@latest -g
或yarn global add pm2
- 安裝 git :不會(huì),看這里
- 配置 SSH,使得服務(wù)器可以免密運(yùn)行
git clone
,不會(huì),看這里!
第二步:開發(fā)機(jī)器環(huán)境配置
- 安裝 node.js :不會(huì),看這里!
- 安裝 pm2 :
npm install pm2@latest -g
或yarn global add pm2
- 配置SSH,免密登錄服務(wù)器,不會(huì),看這里!
// node.js 項(xiàng)目操作步驟配置,注意修改對(duì)應(yīng)的信息
// pm2 init 等同于 pm2 ecosystem,可以生成帶有 deploy 屬性的配置文件:ecosystem.config.js
module.exports = {
apps : [{
name : 'API', //應(yīng)用名
script : 'app.js', //應(yīng)用文件位置
env: {
PM2_SERVE_PATH: ".", //靜態(tài)服務(wù)路徑
PM2_SERVE_PORT: 8080, //靜態(tài)服務(wù)器訪問(wèn)端口
NODE_ENV: 'development' //啟動(dòng)默認(rèn)模式
},
env_production : {
NODE_ENV: 'production' //使用production模式 pm2 start ecosystem.config.js --env production
},
instances:"max", //將應(yīng)用程序分布在所有CPU核心上,可以是整數(shù)或負(fù)數(shù)
watch:true, //監(jiān)聽模式
output: './out.log', //指定日志標(biāo)準(zhǔn)輸出文件及位置
error: './error.log', //錯(cuò)誤輸出日志文件及位置,pm2 install pm2-logrotate進(jìn)行日志文件拆分
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遠(yuǎn)程/分支
repo : 'git@github.com:repo.git', //git地址
path : '/var/www/production', //服務(wù)器文件路徑
post-deploy : 'npm install && pm2 reload ecosystem.config.js --env production' //部署后的動(dòng)作
}
}
};
最后執(zhí)行命令
# pm2 連接服務(wù)器,通知其 git clone 代碼等初始化工作
pm2 deploy production setup
# 啟動(dòng) 或 更新 node.js 項(xiàng)目
# 讓服務(wù)器 git pull 代碼,編譯后啟動(dòng)應(yīng)用
# --force 的作用:如果服務(wù)器本地代碼有改動(dòng),那么放棄改動(dòng),用git倉(cāng)庫(kù)最新代碼更新項(xiàng)目
pm2 deploy production --force;
下面說(shuō)一下命令詳解
# 命令格式
# 如果配置文件名是:ecosystem.config.js或者 pm2.config.js,上面命令可以不用寫 <configuration_file>
pm2 deploy <configuration_file> <environment> <command>
# 此命令就是默認(rèn)尋找 ecosystem.config.js 或 pm2.config.js 配置文件執(zhí)行
pm2 deploy production setup
# 在配置文件中設(shè)定 env_production和 env_development,就可以在執(zhí)行命令時(shí)調(diào)用,把環(huán)境變量傳遞給node.js 項(xiàng)目
# 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可以讓所有服務(wù)器執(zhí)行一次命令
pm2 deploy production exec "pm2 reload all"
# 回滾到上一個(gè)部署版本
pm2 deploy production revert 1
# 部署的幾個(gè)時(shí)間點(diǎn)
"pre-setup" : "在setup執(zhí)行前 運(yùn)行的 命令或腳本",
"post-setup" : "在代碼clone完成后 執(zhí)行的命令或腳本",
"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'"
# 操作多臺(tái)服務(wù)器,只需修改host,單臺(tái)就一個(gè)
"host" : ["212.83.163.1", "212.83.163.2", "212.83.163.3"],
# -------------------------------報(bào)錯(cuò)解決---------------------------
npm: command not found
post-deploy hook failed
Deploy failed
# pm2 部署時(shí),出現(xiàn)上面錯(cuò)誤,但運(yùn)行 npm -v都是正常的,原因是 pm2 的配置文件,按照下面步驟即可解
# 1、打開終端
$ cd ~
$ nano .bashrc
# 2、把下面內(nèi)容注釋掉
#If not running interactively, don 't do anything
case $ - in
*
i * );;
*) return;;
esac
# 3、更新環(huán)境變量
$ source .bashrc
4.6 PM2 開啟文件服務(wù)
https://pm2.keymetrics.io/docs/usage/expose/
# --------------------------------1---------------------------
# 假設(shè) ~/test目錄下有一個(gè) test.txt文件
# 開啟文件服務(wù)器,默認(rèn)端口是8080,可以根據(jù)需要修改
pm2 serve ~/test 8080
# 瀏覽器訪問(wèn)
http://localhost:8080/test.txt
# --------------------------------2---------------------------
# 假設(shè) ~/test目錄下有一個(gè) test.txt文件
# 1、切換到共享目錄
cd ~/test
# 2、新建配置文件 : ecosystem.config.js
pm2 init simple
# 3、修改配置文件為如下內(nèi)容
module.exports = {
apps: [{
name: "serve",
script: "serve",
env: {
PM2_SERVE_PATH: '.',
PM2_SERVE_PORT: 8080
}
}]
}
# 4、啟動(dòng)服務(wù)
pm2 start ecosystem.config.js
#或者
pm2 start
# 5、瀏覽器訪問(wèn)
http://localhost:8080/test.txt
# --------------------------------3---------------------------
# 假設(shè)共享目錄有index.html 文件,文件內(nèi)容如下。訪問(wèn)共享目錄時(shí),默認(rèn)打開 index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>pm2 serve</title>
</head>
<body>
<h1>Welcome</h1>
<p>這是 pm2 服務(wù)器!</p>
</body>
</html>
# ---------命令行啟動(dòng)
# 1、切換到共享目錄
cd ~/test
# 2、啟動(dòng)服務(wù)
pm2 serve --spa
# 3、訪問(wèn)
http://localhost:8080
# ---------配置文件啟動(dòng)
# 1、切換到共享目錄
cd ~/test
# 2、新建配置文件 : ecosystem.config.js
pm2 init simple
# 3、修改配置文件為如下內(nèi)容
module.exports = {
apps: [{
name: "serve",
script: "serve",
env: {
PM2_SERVE_PATH: '.',
PM2_SERVE_PORT: 8080,
PM2_SERVE_SPA: 'true'
}
}]
}
# 4、啟動(dòng)服務(wù)
pm2 start ecosystem.config.js
#或者
pm2 start
# 5、瀏覽器訪問(wèn)
http://localhost:8080
# --------------------------------4---------------------------
# 使用用戶名和密碼來(lái)訪問(wèn)服務(wù)
# --------------命令行啟動(dòng)
# 1、切換到共享目錄
cd ~/test
# 2、啟動(dòng)服務(wù),用戶名:username,密碼:password
pm2 serve --basic-auth-username username --basic-auth-password password
# 3、瀏覽器訪問(wèn)(需要輸入上面用戶名和密碼)
http://localhost:8080
# --------------配置文件啟動(dòng)
# 1、切換到共享目錄
cd ~/test
# 2、新建配置文件 : ecosystem.config.js
pm2 init simple
# 3、修改配置文件為如下內(nèi)容
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、啟動(dòng)服務(wù)
pm2 start ecosystem.config.js
#或者
pm2 start
# 5、瀏覽器訪問(wèn)(需要輸入上面用戶名和密碼)
http://localhost:8080
5、Docker 集成
Supervisor是用Python開發(fā)的一套通用的進(jìn)程管理程序,能將一個(gè)普通的命令行進(jìn)程變?yōu)楹笈_(tái)daemon,并監(jiān)控進(jìn)程狀態(tài),異常退出時(shí)能自動(dòng)重啟,這是另一種監(jiān)控后臺(tái)的方式,詳情可以參考:Supervisor+Dockerfile編譯jdk鏡像
#在容器中安裝 pm2
RUN npm install pm2 -g
# 直接啟動(dòng)應(yīng)用
CMD ["pm2-runtime", "app.js"]
# 通過(guò)配置文件啟動(dòng)
CMD ["pm2-runtime", "ecosystem.config.js"]
**注意:在容器中使用 pm2 啟動(dòng)應(yīng)用時(shí),要使用 pm2-runtime
而不是 pm2 start
, 因?yàn)椋?*pm2 是默認(rèn)后臺(tái)啟動(dòng)的, docker 感知不到。CMD 命令執(zhí)行完成,docker 容器就結(jié)束了。 所以直接使用 node app.js
啟動(dòng)應(yīng)用后,應(yīng)用能一直在容器中保持運(yùn)行。 pm2 以后臺(tái)形式運(yùn)行,CMD 命令執(zhí)行完成,docker 就認(rèn)為可以退出了。所以需要使用 pm2-runtime
來(lái)進(jìn)行處理。pm2-runtime
是為 Docker 容器設(shè)計(jì)的,它將應(yīng)用程序置于前臺(tái),從而使容器保持運(yùn)行狀態(tài)
https://pm2.keymetrics.io/docs/usage/quick-start/
https://www.jianshu.com/p/02af8c5261e5
https://blog.csdn.net/leonnew/article/details/121989900文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-736184.html
https://blog.csdn.net/fanlehai/article/details/121014685文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-736184.html
到了這里,關(guān)于PM2入門及其常用命令的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!