PM2 是 Process Manager 不是 PM2.5!

PM2

前言

PM2 的全名是 Process Manager 2,它是一款 Node.js 的進程管理工具,並不是指 Particulate Matter(懸浮微粒)2.5 的縮寫,所以不要搞錯囉~

PM2(Process Manager 2)是什麼?

首先依照常見的文獻說法會說 PM2 是…

PM2 是 JavaScript 執行環境時的 Node.js 進程管理工具。

雖然這句話看似非常的短,但實質上也包含了很多的內容,所以我們來拆解一下這句話,或許你會更了解 PM2 是什麼用途:

  • JavaScript 執行環境:這句話意思是指 JavaScript 在運作執行時會產生一個環境,也就是我們說的 Runtime(執行環境),這個 Runtime 會負責執行 JavaScript 的程式碼。
  • Node.js:這是一個基於 Chrome V8 引擎的 JavaScript 開發框架,它可以讓 JavaScript 在伺服器端執行,並且可以使用一些系統的 API。
  • 進程管理工具:這是指一個可以管理進程(Process)的工具,所謂的進程就是一個正在運行的程式,而進程管理工具就是可以讓我們管理這些程式的工具。

透過上述拆解說明,我們對於 PM2 是什麼就有一定的基礎概念,但是我們為什麼要用呢?

這邊我舉例一個最簡單的場景,假設你有一個 Node.js 應用程式,你希望它可以一直處於運行狀態下,但應用程式可能會一些我們無法預期的 Bug 而導致程式掛掉,這時候如果沒有使用 PM2 來做管理的話,很常見的狀況就是我們要被 onCall 了,這時候就會需要一個進程管理工具來幫助我們管理這些進程哩~

建立初始環境

首先我們要來建立一個初始環境,這樣在使用 PM2 的時候才會比較有感覺,請你輸入以下指令快速建立一個 Node.js 應用程式:

1
2
3
4
mkdir pm2-example
cd pm2-example
express --no-view
npm install

上方指令我們做了一下行為

  • 建立一個名為 pm2-example 的資料夾
  • 進入 pm2-example 資料夾
  • 使用 express 快速建立一個 Express 應用程式,並且不使用 View Engine(因為我們只是要示範 PM2,所以使用純 API 的方式)
  • 安裝 Express 的相依套件

接著請務必養成一個習慣,專案建立完畢後,請先執行一次程式,確保程式可以正常運行,這樣在後續使用 PM2 的時候才不會有問題:

1
npm start

你現在已經可以透過 Postman 來去測試你的 API

1
GET http://localhost:3000/users

不意外應該會回傳以下結果:

1
respond with a resource

到這邊為主,代表你的專案是正常運作的,後面我們會再微調一下專案,讓它可以透過 PM2 來管理,而不是我們手動去輸入 npm start 來啟動。

安裝 PM2

首先請打開終端機,並輸入以下指令:

1
npm install pm2 -g

這樣就安裝完畢,非常的簡單呢!當然,如果你是使用 yarn 的話,也可以使用以下指令:

1
yarn global add pm2

PM2 的基本操作

使用的方式非常簡單,你主要需要記得的指令為以下:

  • pm2 start <檔案名稱>:啟動一個應用程式

就是這麼簡單,如果是直接啟動一個專案時,通常可能的指令會是:

1
pm2 start app.js

但是我們的專案是使用 Express 來產生的專案,所以我們要修改一下指令:

1
pm2 start bin/www

輸入完畢後,你就可以看到以下畫面:

Start

此時你會發現終端機跟以前完全不一樣,原本你輸入 npm start 會看到以下狀況:

npm start

而使用 PM2 後,我們會發現所有的請求以及畫面都不會再呈現於終端機畫面上,這是因為 PM2 啟動專案後,它會將該啟動行為轉移到背景執行,這樣我們就可以不用擔心終端機關閉後,專案就會停止運行的問題。

查看 PM2 狀態與列表

那這時候問題來了,我們該怎麼查看 PM2 的狀態呢?首先你必須要先使用 pm2 list 來查看目前 PM2 的狀態:

1
pm2 list

這時候你會看到運行於 PM2 上的專案:

PM2

這個畫面類似於儀表板,可以讓你查看目前 PM2 上運行的專案,以及一些基本資訊。

其中,其實有很多語法可以使用,例如:

  • pm2 status
  • pm2 ls
  • pm2 list

這些指令都是可以查看目前 PM2 上運行的專案,而我自己比較習慣使用 pm2 list 這個指令。

底下我也條列每個欄位的意義:

  • id:專案的 ID,由 PM2 自動產生
  • name:專案的名稱,通常是專案的檔案名稱,預設會是指令後面的檔案名稱,如:bin/www => www
  • namespace:專案的命名空間,預設為 default,簡單來講就是專案的群組
  • version:專案的版本,PM2 會參考 package.json 的版本
  • mode:專案的模式,通常是 fork,也就是單一進程模式,當然也可以是 cluster,也就是多進程模式
  • pid:專案的 PID,也就是 Process ID
  • uptime:專案的運行時間,也就是啟動後的時間
  • status:專案的狀態,通常是 online,主要有 online(運作中)、stopped(專案已停止)、errored(發生錯誤)、launching(正在啟動) 以及unknown(狀態未知) 等狀態
  • cpu:專案的 CPU 使用率
  • mem:專案的記憶體使用率
  • user:專案的使用者,這會撈取目前使用者的名稱
  • watching:專案是否有監聽檔案變化,通常是 false,當有監聽檔案變化時,會是 true

查看 PM2 Logs

接著我們要查看該專案運行的 Logs 呢?只需要輸入以下指令即可:

1
pm2 logs <專案名稱/ID/名稱空間>

以我們範例來講,就是:

1
2
3
pm2 logs 0 # 0 是專案的 ID
pm2 logs www # www 是專案的名稱
pm2 logs default # default 是專案的名稱空間

這樣就可以持續查看專案的 Logs 了!

Logs

我這邊也詳細說明一下 pm2 logs 的指令:

  • pm2 logs:查看所有專案的 Logs
  • pm2 logs <專案名稱/ID>:查看指定專案的 Logs
  • pm2 logs <命名空間>:概念其實類似於群組,你可以將專案分類,這樣就可以使用命名空間來查看該群組的 Logs

除此之外,pm2 logs 搭配不同的參數,可以讓你更精準的查看 Logs,例如:

  • pm2 logs --out:只查看標準輸出,也就是正常輸出
  • pm2 logs --err:只查看錯誤輸出
  • pm2 logs --json > logs.json:將 Logs 輸出成 JSON 格式,這樣你就可以透過程式來處理 Logs
  • pm2 logs <專案名稱/ID> | grep "關鍵字":查看特定關鍵字的 Logs,概念就是一個篩選器,例如:pm2 logs www | grep "GET",就可以查看所有 GET 的 Logs
  • pm2 logs <專案名稱/ID> --lines 100:只查看最後 100 行的 Logs,也就是最新的 100 行

以上差不多是很常用的指令。

傳遞參數給 pm2 start

pm2 start 並不是這麼單純的指令,你可以透過傳遞參數給 pm2 start 來做更多的事情,例如:

  • --name:指定專案名稱
  • --watch:監聽檔案變化,當檔案變化時,自動重新啟動專案
  • --cron-restart:透過 Cron 表達式定時重新啟動專案
  • --max-memory-restart:當記憶體使用超過指定值時,自動重新啟動專案
  • --namespace:指定專案名稱空間

這邊我舉例一個常見的使用方式:

1
pm2 start bin/www --name "hexschool-example" --watch

這樣就可以指定專案名稱為 hexschool-example,並且監聽檔案變化,當檔案變化時,自動重新啟動專案。

如果我想要指定專案名稱空間的話,可以這樣做:

1
pm2 start bin/www --namespace "hexschool" --watch

如果想要同時更改專案名稱以及名稱空間的話,可以這樣做:

1
pm2 start bin/www --name "hexschool-example" --namespace "hexschool" --watch

這樣就可以同時指定專案名稱以及名稱空間了!

重新啟動專案

當你的專案有異常時,你可以透過 pm2 restart 來重新啟動專案:

1
pm2 restart <專案名稱/ID/名稱空間>

如果是想要重新啟動所有專案的話,可以這樣做:

1
pm2 restart all

停止專案

當你的專案不再需要運行時,你可以透過 pm2 stop 來停止專案:

1
pm2 stop <專案名稱/ID/名稱空間>

如果是想要停止所有專案的話,可以這樣做:

1
pm2 stop all

刪除專案

請注意,輸入 pm2 stop 並不會刪除專案,只是停止專案而已,如果你想要刪除專案的話,可以透過 pm2 delete 來刪除專案:

1
pm2 delete <專案名稱/ID/名稱空間>

如果是想要刪除所有專案的話,可以這樣做:

1
pm2 delete all

PM2 進階設定(Ecosystem File)

PM2 有一個進階的設定檔案,稱為 Ecosystem File,你可以透過這個檔案直接做到更多的設定,而 Ecosystem File 支援 JavaScript、JSON 以及 YAML 格式。

但以實戰來講,比較常見使用 ecosystem.config.js(JavaScript 格式)。

那麼我們該如何使用呢?你只需要輸入以下指令,PM2 就會自動幫你產出一個 Ecosystem File(ecosystem.config.js):

1
pm2 ecosystem

基本上他會基於你當前的專案環境,產出一個 Ecosystem File,這樣你就可以直接使用這個檔案來做進階設定。

格式大概長這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module.exports = {
apps : [{
script: 'index.js',
watch: '.'
}, {
script: './service-worker/',
watch: ['./service-worker']
}],

deploy : {
production : {
user : 'SSH_USERNAME',
host : 'SSH_HOSTMACHINE',
ref : 'origin/master',
repo : 'GIT_REPOSITORY',
path : 'DESTINATION_PATH',
'pre-deploy-local': '',
'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production',
'pre-setup': ''
}
}
};

因此我們可以看到 PM2 非常之強大,你可以透過 Ecosystem File 來做到更多的設定。

那麼以上就是 PM2 的基本操作,希望你可以透過這篇文章來了解 PM2 的基本操作,並且可以在你的專案中使用 PM2 來管理你的 Node.js 應用程式 :D

ps. PM2 不單純只是可以用於 Node.js,你也可以使用 PM2 來管理其他的應用程式,例如:Python、Ruby、Java 等等。

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
或者你可以也可以請我「喝一杯咖啡(Donate)」。

Buy Me A Coffee Buy Me A Coffee

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ