pm2入坑詳解

一、概述

1、pm2是什么?
pm2是node進(jìn)程管理工具。

2、為什么選它?與其他工具的對(duì)比


對(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)使用輪詢的方式達(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ì)有如下打印。

啟動(dòng)

(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)程是否在線
(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

所有進(jìn)程

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ù))


image.png

第二張圖是指代碼指標(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分位)


image.png

7、查看日志:pm2 logs

會(huì)打印下面的信息。但是一般不這么看,一般直接進(jìn)入紅框的路徑,直接用less 命令查看日志文件。


image.png

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ī)


image.png

9、啟動(dòng)命令(start)還可以帶參數(shù)

--name
給進(jìn)程命名
--watch
是否開(kāi)啟自動(dòng)重啟--max-memory-restart
最大重啟內(nèi)存
--log
指定日志文件路徑
-- arg1 arg2 arg3
其他參數(shù)

=========================================我是分割線==================================

  • 小結(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ǔ)類

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)階類

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)日志類

log_date_format :日志時(shí)間格式
error_file :錯(cuò)誤日志存放路徑
out_file :全部日志存放路徑
combine_logs:是否將不同id的進(jìn)程日志合并
merge_logs:同上

(4)控制流

min_uptime :pm2認(rèn)為進(jì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)程掉線后,等待多長(zhǎng)時(shí)間重啟
autorestart: 是否開(kāi)啟自動(dòng)重啟

其實(shí)還有一個(gè) 部署類,但是因?yàn)樵谖业膱?chǎng)景中用不上,就沒(méi)介紹,詳細(xì)可以看官方文檔。

4、m站最佳實(shí)踐

  • pm2配置文件是一個(gè)單獨(dú)的工程(pm2-server)


    image.png
(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)
mingling.png

命令解釋:

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)部署
bushu.png

前置條件:
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只收集日志,通??梢耘浜蟨m2-logrotate插件來(lái)管理日志,如修改日志文件名,日志分割,日志文件數(shù)量管理,自動(dòng)刪除早期日志等。


image.png

2、pm2-web

pm2 服務(wù)狀態(tài)監(jiān)控程序,默認(rèn)9615端口,返回該機(jī)器的信息,node進(jìn)程的信息。

image.png
image.png

3、pm2.io

pm2的可視化實(shí)時(shí)監(jiān)控(收費(fèi))
(1)服務(wù)器信息
(2)進(jìn)程信息:重啟次數(shù),cpu使用率,內(nèi)存占用,event loop延遲,報(bào)錯(cuò)郵件提醒等


image.png

四、自研監(jiān)控

其實(shí)利用pm2-web,輪詢它提供的接口,做一個(gè)可視化。展示圖片就不放上來(lái)了。

主要觀察指標(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í)討論。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容