pm2 的 watch 是用於監聽檔案變動,自動重啟服務的一個功能。我們可以透過在 pm2.config.js 檔案中設定 watch: true 來開啟此功能。這樣一旦進了新 code 就會自動重啟,不用手動 pm2 restart {id} 非常方便。
但也就是因為這麼方便,所以常常會忘了他的存在。
前陣子做了一個透過排程,自動到某處去下載json檔案回來存放,再提供一隻API來吐出篩選過的資料的小工具。在開發環境完成後,一樣就很順手的在正式環境用PM2跑起來。
但卻不知道為什麼,每次Call API的時候,並非都成功,常常遇到噴 500 的狀況。為此還一直驗證程式碼的各個細節,但卻找不到原因。此時我執行了 pm2 stop {id},然後再重啟 pm2 start {id},卻發現剛剛的問題消失了!
當過了幾天,我用 pm2 status 發現,這個專案的 pm2 watch 不知道為什麼變成 disabled,於是我將它先 delete,再重新用 pm2 start pm2.config.js 重啟,這時候 watch 就恢復正常了。
但這時候竟然又發生之前那個會噴 500 的狀況!!!
當我打開 PM2 monit 的時候才發現原來他一直在被反覆關掉重啟、關掉重啟…,此時才意識到應該是 watch 的關係。
這個工具每次啟動時,就會直接去拉一次資料。再來會用排程每天去拉資料。而 watch 機制在啟動後抓完資料存檔完畢時,偵測到檔案變動,就又立刻重啟。重啟後因為又再一次執行下載檔案,pm2又再次偵測到檔案變動,因此再次重啟。就這樣變成無限迴圈的抓資料然後重啟。
但為什麼之前先 pm2 stop {id} 後再 pm2 start {id} 會正常呢?因為在這個情況下,watch會被關掉。要透過 pm2 start pm2.config.js 才會啟動 watch。
回到問題本身,該如何解決不要 watch 特定目錄的的問題。很簡單,只要在 pm2.config.js 裡加上 ignore_watch: [‘你想忽略的目錄’]即可,例如:
module.exports = { apps: [ { name: "App Name", script: "npm start", watch: true, ignore_watch: [".temp"], env: { ... } } ] }