一、概述
1适滓、pm2是什么敦迄?
pm2是node進(jìn)程管理工具。
2、為什么選它颅崩?與其他工具的對(duì)比
二几于、特性
1、后臺(tái)運(yùn)行
普通啟動(dòng)方式:node index.js沿后,關(guān)閉終端就結(jié)束進(jìn)程沿彭;
pm2可以后臺(tái)運(yùn)行,終端關(guān)閉不影響尖滚。
2喉刘、自動(dòng)重啟
可以監(jiān)聽(tīng)某些文件改動(dòng),自動(dòng)重啟
3漆弄、停止不穩(wěn)定的進(jìn)程
限制不穩(wěn)定的重啟的次數(shù)睦裳,達(dá)到上限就停止進(jìn)程。
4撼唾、0 秒停機(jī)重啟
集群模式下廉邑,可以達(dá)到重啟時(shí)不停止服務(wù)。
5倒谷、簡(jiǎn)單日志管理
pm2可以收集日志蛛蒙,并有插件配合進(jìn)行管理。后面會(huì)提到渤愁。
6牵祟、自動(dòng)負(fù)載均衡
cluster模式下,會(huì)自動(dòng)使用輪詢(xún)的方式達(dá)到負(fù)載均衡抖格,從而減輕服務(wù)器的壓力诺苹。
7、提供實(shí)時(shí)的接口
pm2插件提供實(shí)時(shí)的接口雹拄,返回服務(wù)器與進(jìn)程的信息收奔,后面會(huì)提到。
8办桨、集成管理
對(duì)于多個(gè)進(jìn)程筹淫,不同環(huán)境,可以統(tǒng)一配置呢撞,方便管理损姜。
三、基礎(chǔ)用法
1殊霞、啟動(dòng)進(jìn)程: pm2 start app.js
app.js是node的啟動(dòng)文件摧阅,控制臺(tái)會(huì)有如下打印。
(1)其中app name 和id都是這個(gè)進(jìn)程的標(biāo)識(shí)绷蹲,可以對(duì)他們進(jìn)行別的操作棒卷,比如stop顾孽,delete等。
(2)mode:進(jìn)程模式比规,cluster或fork若厚。cluster有多個(gè)進(jìn)程,而fork只有一個(gè)蜒什。
(3)status:進(jìn)程是否在線(xiàn)
(4)restart:重啟次數(shù)
(5)uptime:運(yùn)行時(shí)間
(6)cpu:cpu占用率
(7)mem:內(nèi)存占用大小
2测秸、停止進(jìn)程:pm2 stop app_name|app_id|all
3、刪除進(jìn)程:pm2 delete app_name|app_id|all
4灾常、重啟進(jìn)程:pm2 restart/reload app_name|app_id|all
集群模式下霎冯,restart中斷服務(wù),而reload不會(huì)
5钞瀑、查看所有的進(jìn)程:pm2 list/ls/status
id編號(hào)從1~4的是一個(gè)應(yīng)用沈撞,分別對(duì)應(yīng)4個(gè)進(jìn)程。
6雕什、查看某一個(gè)進(jìn)程的信息:pm2 show app_name|app_id
第一張圖是指進(jìn)程的信息缠俺,比如status(狀態(tài))、restarts(重啟次數(shù))监徘、uptime(運(yùn)行時(shí)間)晋修、script path(啟動(dòng)入口的路徑)、script args(啟動(dòng)文件的參數(shù))凰盔、error log path(錯(cuò)誤日志的路徑)、out log path(輸出日志的路徑)倦春、exec mode(進(jìn)程的模式)户敬、watch&reload(是否開(kāi)啟監(jiān)聽(tīng)文件變動(dòng)重啟)、unstable restarts(不穩(wěn)定的重啟次數(shù))
第二張圖是指代碼指標(biāo):heap size(堆內(nèi)存)睁本、heap usage(堆內(nèi)存使用率)尿庐、used heap size(堆內(nèi)存使用情況)、event loop latency(事件循環(huán)時(shí)延)呢堰、event loop latency p95(事件循環(huán)時(shí)延 第95分位)
7抄瑟、查看日志:pm2 logs
會(huì)打印下面的信息。但是一般不這么看枉疼,一般直接進(jìn)入紅框的路徑皮假,直接用less 命令查看日志文件。
8骂维、監(jiān)控所有進(jìn)程:pm2 monit
左上角是進(jìn)程的列舉惹资,右上角是全部的實(shí)時(shí)日志,左下角是選中進(jìn)程的代碼指標(biāo)航闺,右下角是進(jìn)程的信息褪测。
但是這樣有2個(gè)不好的地方:
(1)不可能這樣一直開(kāi)著終端看監(jiān)控
(2)比較容易死機(jī)
9猴誊、啟動(dòng)命令(start)還可以帶參數(shù)
--name
給進(jìn)程命名
--watch
是否開(kāi)啟自動(dòng)重啟--max-memory-restart
最大重啟內(nèi)存
--log
指定日志文件路徑
-- arg1 arg2 arg3
其他參數(shù)
=========================================我是分割線(xiàn)==================================
- 小結(jié):
上面介紹的這些啟動(dòng)其實(shí)有弊端:
1、通過(guò)命令行傳遞參數(shù)侮措,無(wú)法記住到底傳遞過(guò)哪些參數(shù)懈叹。
2、對(duì)于多個(gè)進(jìn)程分扎,不方便管理项阴。
請(qǐng)見(jiàn)下章的大招
四、集成部署(Ecosystem File)
1笆包、why
(1)不同環(huán)境(dev环揽、test、master)
(2)通過(guò)命令行傳遞參數(shù)不方便
(3) 同時(shí)管理多個(gè)應(yīng)用
2庵佣、how
生成一個(gè)配置文件:pm2 ecosystem
app是要管理應(yīng)用的數(shù)組歉胶,每個(gè)對(duì)象都是一個(gè)應(yīng)用的配置。
module.exports = {
apps: [
{
name: "app",
script: './app.js',
env: {
NODE_ENV: "development",
},
evn_master: {
NODE_ENV: "master"
}
}
]
}
3巴粪、配置項(xiàng)
(1)基礎(chǔ)類(lèi)
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ù)
(2)進(jìn)階類(lèi)
instances :進(jìn)程數(shù)
exec_mode :進(jìn)程的模式(cluster或fork)
- ps: cluster模式利用node的child_process模塊孵化多個(gè)子進(jìn)程通今,主進(jìn)程監(jiān)聽(tīng)端口,子進(jìn)程只和主進(jìn)程通信肛根,從而
達(dá)到單個(gè)端口多個(gè)進(jìn)程辫塌;通過(guò)輪轉(zhuǎn)方式實(shí)現(xiàn)負(fù)載均衡。
watch :布爾值或文件數(shù)組派哲,允許開(kāi)啟監(jiān)聽(tīng)文件改動(dòng)重啟
ignore_watch :不監(jiān)聽(tīng)的文件
max_memory_restart :超過(guò)該內(nèi)存就自動(dòng)重啟
env :應(yīng)用中的默認(rèn)環(huán)境變量
env_ :命令行中可傳入的環(huán)境變量臼氨,覆蓋默認(rèn)環(huán)境變量
source_map_support :默認(rèn)true,支持sourcemap文件
(3)日志類(lèi)
log_date_format :日志時(shí)間格式
error_file :錯(cuò)誤日志存放路徑
out_file :全部日志存放路徑
combine_logs:是否將不同id的進(jìn)程日志合并
merge_logs:同上
(4)控制流
min_uptime :pm2認(rèn)為進(jìn)程在線(xiàn)的最小時(shí)長(zhǎng)
listen_timeout :如果app沒(méi)有發(fā)送ready信號(hào)芭届,間隔多長(zhǎng)時(shí)間reload
kill_timeout :從告訴進(jìn)程要關(guān)閉到強(qiáng)制關(guān)閉進(jìn)程的間隔時(shí)間
wait_ready:是否等待進(jìn)程發(fā)送ready信號(hào)
max_restarts :最大不穩(wěn)定重啟次數(shù)(不穩(wěn)定指的是小于1s或者小于的min_uptime重啟)
restart_delay:進(jìn)程掉線(xiàn)后储矩,等待多長(zhǎng)時(shí)間重啟
autorestart: 是否開(kāi)啟自動(dòng)重啟
其實(shí)還有一個(gè) 部署類(lèi),但是因?yàn)樵谖业膱?chǎng)景中用不上褂乍,就沒(méi)介紹持隧,詳細(xì)可以看官方文檔。
4逃片、m站最佳實(shí)踐
-
pm2配置文件是一個(gè)單獨(dú)的工程(pm2-server)
(1)配置踩坑經(jīng)歷:
a)script:若使用cluster模式屡拨,必須是啟動(dòng)文件入口,不可通過(guò)nuxt start啟動(dòng)
b) max_restarts:指不穩(wěn)定重啟褥实,即小于1s或min_uptime的重啟呀狼,要結(jié)合min_uptime配置才起效
c) listen_timeout:當(dāng)cluster模式時(shí),這個(gè)值要大于一個(gè)進(jìn)程啟動(dòng)所需時(shí)間性锭,否則reload時(shí)會(huì)造成短暫的服務(wù)不可用
踩坑經(jīng)歷:
(1)script:若使用cluster模式赠潦,必須是啟動(dòng)文件入口,不可通過(guò)npm啟動(dòng)
(2)max_restarts:指不穩(wěn)定重啟草冈,即小于1s或min_uptime的重啟她奥,要結(jié)合min_uptime配置才起效
(3)listen_timeout:當(dāng)cluster模式時(shí)瓮增,這個(gè)值要大于一個(gè)進(jìn)程啟動(dòng)所需時(shí)間,否則reload時(shí)會(huì)造成短暫的服務(wù)不可用
(2)配置啟動(dòng)命令(package.json)
命令解釋?zhuān)?/p>
cross-env NODE_ENV=development pm2 start pm2-conf/ecosystem.config.js --only detective --env test
1哩俭、 cross-env NODE_ENV=development 绷跑,pm2-server工程的環(huán)境變量,目的是區(qū)分各個(gè)環(huán)境的應(yīng)用啟動(dòng)路徑
2凡资、 pm2 start pm2-conf/ecosystem.config.js 砸捏,pm2的啟動(dòng)命令
3、 --only detective --env test 隙赁,傳遞給pm2的參數(shù)垦藏,-- only <name>,--env <env name>
(3)部署
前置條件:
pm2的ecosystem file單獨(dú)作為一個(gè)工程(pm2-server)伞访,與其他工程一樣的方法拷貝至服務(wù)器
m站構(gòu)建流程:
1掂骏、jenkins從git上拉取代碼
2、構(gòu)建完厚掷,壓縮拷貝至服務(wù)器
3弟灼、在服務(wù)器上切換至pm2-server目錄,通過(guò)pm2命令啟動(dòng)m站 (npm run reloadM)
即:
cross-env NODE_ENV=master pm2 reload pm2-conf/ecosystem.config.js --only mweb --env master
五冒黑、Graceful start/shutdown
1田绑、start
有時(shí)候需要等待進(jìn)程與數(shù)據(jù)庫(kù)或者其他建立起鏈接之后再啟動(dòng),希望pm2等待這段時(shí)間再去啟動(dòng)進(jìn)程抡爹。這個(gè)時(shí)候就要配置wait_ready: true掩驱;同時(shí)在進(jìn)程準(zhǔn)備好時(shí)發(fā)送process.send('ready')
var http = require('http');
var app = http.createServer(function(req, res) {
res.writeHead(200);
res.end('hey');
})
var listener = app.listen(0, function() {
console.log('Listening on port ' + listener.address().port);
// Here we send the ready signal to PM2
process.send('ready');
});
2、shutdown
(1)當(dāng)restart/reload/stop進(jìn)程時(shí)豁延,pm2會(huì)向進(jìn)程發(fā)送一個(gè)SIGINT信號(hào)昙篙,告訴進(jìn)程將會(huì)被停止; *當(dāng)進(jìn)程接到pm2的SIGINT信號(hào)時(shí)诱咏,可以終止所有連接,清除所有任務(wù)缴挖,這樣就可以【干凈利索】的關(guān)閉進(jìn)程
(2)如果進(jìn)程1.6s內(nèi)(參數(shù):kill_timeout袋狞,默認(rèn)1600ms)沒(méi)有停止,pm2會(huì)發(fā)送一個(gè)SIGKILL信號(hào)映屋,之后強(qiáng)制進(jìn)程退出苟鸯。
process.on('SIGINT', function() {
db.stop(function(err) {
process.exit(err ? 1 : 0);
});
});
六、pm2插件
1棚点、pm2-logrorate
pm2只收集日志早处,通常可以配合pm2-logrotate插件來(lái)管理日志瘫析,如修改日志文件名砌梆,日志分割默责,日志文件數(shù)量管理,自動(dòng)刪除早期日志等咸包。
2桃序、pm2-web
pm2 服務(wù)狀態(tài)監(jiān)控程序,默認(rèn)9615端口烂瘫,返回該機(jī)器的信息媒熊,node進(jìn)程的信息。
3坟比、pm2.io
pm2的可視化實(shí)時(shí)監(jiān)控(收費(fèi))
(1)服務(wù)器信息
(2)進(jìn)程信息:重啟次數(shù)芦鳍,cpu使用率,內(nèi)存占用葛账,event loop延遲柠衅,報(bào)錯(cuò)郵件提醒等
四、自研監(jiān)控
其實(shí)利用pm2-web注竿,輪詢(xún)它提供的接口茄茁,做一個(gè)可視化。展示圖片就不放上來(lái)了巩割。
主要觀(guān)察指標(biāo):
- 進(jìn)程狀態(tài):online
- 重啟次數(shù):一定范圍
- 內(nèi)存使用:穩(wěn)定
- cpu占用率:穩(wěn)定
- 平均負(fù)載:大于0.7有壓力裙顽,持續(xù)大于1.2危險(xiǎn)
結(jié)語(yǔ):
其實(shí)有很多pm2功能還沒(méi)有提到,因?yàn)樽约簺](méi)用到所以也沒(méi)有去細(xì)究宣谈。有感興趣的可以互相學(xué)習(xí)討論愈犹。