爲什麼都用 PM2 來跑 Node 應用?
在服務器上,我們不會直接跑 node,而會用 pm2 來跑。
爲什麼要用 pm2 呢?它解決了啥問題?
想一下:
-
如果你的 node 應用跑的時候突然拋了個錯,崩潰了,是不是需要重新跑起來?這時候是不是就需要另一個進程來自動做重啓這件事情?
-
node 應用的日誌默認輸出在控制檯,如果想輸出到不同的日誌文件,是不是可以讓另一個進程獲取 node 應用的輸出,然後寫文件來實現?
-
node 是單線程的,而機器是多個 cpu 的,爲了充分利用 cpu 的能力,我們會用多個進程來跑 node 應用,這種通用邏輯是不是也可以放到一個單獨進程裏來實現?
-
node 運行時的 cpu、內存等資源的佔用,是不是需要監控?這時候是不是可以讓另一個進程來做?
線上的 node 應用不只是跑起來就行了,還要做自動重啓、日誌、多進程、監控這些事情。
而這些事情,都可以用 pm2 來做。
pm2 是 process manager,進程管理,它是第二個大版本,和前一個版本差異很大,所以叫 pm2.
pm2 的主要功能就是進程管理、日誌管理、負載均衡、性能監控這些。
我們分別來看一下:
首先安裝 pm2:
npm install -g pm2
然後跑一個 node 應用,我這裏跑一個 Nest.js 的應用:
直接 node 跑是這樣的,日誌打印在控制檯:
而用 pm2 的話,就可以這樣跑:
pm2 start ./dist/main.js
它會把這個 node 進程跑起來,然後管理起來:
管理起來之後,就有我們上面說的那些功能了,比如自動重啓、日誌管理、性能監控等。
首先看下日誌,執行
pm2 logs
可以看到 pm2 會把所有進程的日誌打印出來,通過前面的 “進程 id | 進程名字” 來區分,比如 0|main。
而且,它會把它寫到日誌文件裏,在 ~/.pm2/logs 下,以 “進程名 - out.log” 和“進程名 - error.log”分別保存不同進程的日誌:
比如 main-out.log 裏保存了 main 進程的正常日誌,而 main-error.log 裏保存了它的報錯日誌:
我們再跑一個進程試試:
pm2 logs 進程名/進程id
這樣查看單個進程的日誌:
這就是 pm2 的日誌管理的功能。
進程管理的話就是可以手動啓動、重啓、停止某個進程,而且崩潰了會自動重啓,也可以定時自動重啓。
只需要 pm2 start 的時候帶上幾個選項就好了:
超過 200M 內存自動重啓:
pm2 start xxx --max-memory-restart 200M
從 2s 開始每 3s 重啓一次:
pm2 start xxx --cron-restart "2/3 * * * * *"
當文件內容改變自動重啓:
pm2 start xxx --watch
不自動重啓:
pm2 start xxx --no-autorestart
我們分別試一下:
把之前的進程刪掉:
pm2 delete 0
我們指定 1k 內存就重啓:
pm2 start xxx --max-memory-restart 1K
然後在 nest 代碼裏用超過 1k 的內存:
先把之前的日誌清空,使用 pm2 flush 或者 pm2 flush 進程名 | id
確實清空了:
訪問下這個 controller:
查看 main 進程的前 100 行日誌:
pm2 logs main --lines 100
明顯看到重啓了。
這是超過內存的自動重啓。
崩潰的自動重啓、定時自動重啓、文件變動自動重啓等也是類似 。
我們前面用到的 pm2 start、pm2 stop、pm2 restart、pm2 delete 等就是進程管理的功能。
再就是負載均衡,node 應用是單進程的,而爲了充分利用多核 cpu,我們會使用多進程來提高性能。
node 提供的 cluster 模塊就是做這個的,pm2 就是基於這個實現了負載均衡。
我們只要啓動進程的時候加上 -i num 就是啓動 num 個進程做負載均衡的意思。
pm2 start app.js -i max
pm2 start app.js -i 0
這倆是啓動 cpu 數量的進程。
用多進程的方式跑 nest 應用:
可以看到啓動了 8 個進程,因爲我是 8 核 cpu。
跑起來之後,還可以動態調整進程數,通過 pm2 scale:
pm2 scale main 3
我把 main 的集羣調整爲 3 個進程:
可以看到 pm2 刪除了 5 個,留下了 3 個。
pm2 scale main +3
我又加了 3 個,現在變成了 6 個:
可以動態伸縮進程的數量,pm2 會把請求分配到不同進程上去。
這就是負載均衡功能。
此外,還有個性能監控功能,執行 pm2 monit:
pm2 monit
可以看到不同進程的 cpu 和內存佔用情況。
大概就是這些功能,但是當進程多了之後,難道都要手動通過命令行來啓動麼?
肯定不會每次都敲一遍。
pm2 支持配置文件的方式啓動多個應用。
執行 pm2 ecosystem,會創建一個配置文件:
apps 部分就是配置應用的,scripts 就是應用的啓動路徑:
它可以指定的配置非常多,基本就是命令行有啥選項,這裏就有啥屬性:
然後 pm2 start ecosystem.config.js 就可以批量跑一批應用。
就相當於 pm2 根據配置文件自動執行這些命令,不用我們手動敲了。
這樣,我們就可以把啓動的選項保存在配置文件裏。
最後,還有個 pm2 plus,這個是收費功能,看看就行:
訪問 pm2 的網站,登錄,創建 bucket:
然後在本地執行 pm2 link xxx xxx,把本地的 pm2 和那個網站關聯起來:
再執行 pm2 plus 就會打開 bucket 對應的網頁:
可以在線監控你的應用:
下面這些 plus 的功能都是收費的:
一般也不需要用,用免費的本地功能就好了。
總結
服務器上的 node 應用需要用 pm2 的日誌管理、進程管理、負載均衡、性能監控等功能。
分別對應 pm2 logs、pm2 start/restart/stop/delte、pm2 start -i、pm2 monit 等命令。
多個應用或者想把啓動選項保存下來的時候,可以通過 ecosystem 配置文件,批量啓動一系列應用。
不管是出於穩定性、性能還是可觀測性等目的,pm2 都是必不可少的。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/GyKx5tcvVjUCNgbe9Jl05w