天天看點

pm2用法詳解+ecosystem.config

對于背景程序的管理,常用的工具是crontab,可用于兩種場景:定時任務和常駐腳本。關于常駐腳本,今天介紹一款更好用的工具:pm2,基于nodejs開發的程序管理器,适用于背景常駐腳本管理,同時對node網絡應用有自建負載均衡功能。官方的說法,pm2 是一個帶有負載均衡功能的Node應用的程序管理器,個人認為,并不準确,因為pm2支援多種語言,隻是對于除node之外的其他程序無負載均衡的能力。

一,pm2特點:

說一些pm2有哪些優點好處呢?

  1. 支援程序行為配置 ,即可以通過配置,實作對pm2管理應用的一些基礎屬性更新修改,如應用名稱,啟動模式等;
  2. 支援叢集模式,支援負載均衡,但因采用nodejs的cluster子產品實作,僅适用于nodejs程序;
  3. 支援source map,此項針對js, source map檔案是js源檔案的資訊檔案,裡面存儲着源檔案的位置資訊;
  4. 支援熱重新開機;
  5. 支援部署工作流,pm2可依據測試環境和線上環境自動部署到不同的伺服器,同時運作在不同配置下;
  6. 支援監聽重新開機,在檔案更新等情況下可實作程序自動重新開機;
  7. 支援linux的startup程序啟動,startup是指系統boot, 程序自啟動,如centos的chkconfig;
  8. 日志管理,兩種日志,pm2系統日志與管理的程序日志,預設會把程序的控制台輸出記錄到日志中;
  9. 指令自動補全功能,個人感覺這個功能意義不大,而且嘗試了一下,沒有原生的linux指令自動補全反應靈活;
  10. 監控功能,pm2 monit監控cpu和memory使用情況,keymetrics監控更為詳細;
  11. 支援開發調試模式,非背景運作,pm2-dev start <appName>;
  12. 支援pm2子產品開發,實作pm2的功能擴充;
  13. keymetrics監控,比pm2 monit監控更為詳細友好,通過web頁面展示;
  14. 最大記憶體重新開機,設定最大記憶體限制,超過限制自動重新開機;
  15. 程式設計API,提供API供開發者通過程式設計方式靈活管理程序;

以上簡要概述了pm2程序管理工具的特點。

二,pm2常用指令

常用指令通常都是比較簡單。下面列舉一些pm2常用的管理指令

  1. pm2 start <script_file|config_file> [options] 啟動指定應用,如pm2 start index.js --name httpServer;
  2. pm2 stop <appName> [options] 停止指定應用,如pm2 stop httpServer;
  3. pm2 reload|restart <appName> [options]  重新開機指定應用,如pm2 restart httpServer;
  4. pm2 show <appName> [options] 顯示指定應用詳情,如pm2 show httpServer;
  5. pm2 delete <appName> [options] 删除指定應用,如pm2 delete httpServer,如果修改應用配置行為,最好先删除應用後,重新啟動方才生效,如修改腳本入口檔案;
  6. pm2 kill 殺掉pm2管理的所有程序;
  7. pm2 logs <appName>  檢視指定應用的日志,即标準輸出和标準錯誤;
  8. pm2 monit 監控各個應用程序cpu和memory使用情況;

三,pm2常用配置

pm2 配置方式

  1. 指令行方式

    pm2 start index.js --name HttpServer --interpreter node

    此處通過指令的選項配置應用名稱為httpServer,index.js腳本檔案解釋器為node,更多選項可檢視pm2 --help擷取;

  2. 配置檔案方式

    pm2配置檔案方式支援yml與json格式

    processes.yml檔案

apps:
  - script   : ./api.js
    name     : 'api-app'
    instances: 4
    exec_mode: cluster
  - script : ./worker.js
    name   : 'worker'
    watch  : true
    env    :
      NODE_ENV: development
    env_production:
      NODE_ENV: production      

processes.json

{
  apps : [{
    name        : "worker",
    script      : "./worker.js",
    watch       : true,
    env: {
      "NODE_ENV": "development",
    },
    env_production : {
       "NODE_ENV": "production"
    }
  },{
    name       : "api-app",
    script     : "./api.js",
    instances  : 4,
    exec_mode  : "cluster"
  }]}      

 配置項

  1. name  應用程序名稱;
  2. script  啟動腳本路徑;
  3. cwd  應用啟動的路徑,關于script與cwd的差別舉例說明:在/home/polo/目錄下運作/data/release/node/index.js,此處script為/data/release/node/index.js,cwd為/home/polo/;
  4. args  傳遞給腳本的參數;
  5. interpreter  指定的腳本解釋器;
  6. interpreter_args  傳遞給解釋器的參數;
  7. instances  應用啟動執行個體個數,僅在cluster模式有效,預設為fork;
  8. exec_mode  應用啟動模式,支援fork和cluster模式;
  9. watch  監聽重新開機,啟用情況下,檔案夾或子檔案夾下變化應用自動重新開機;
  10. ignore_watch  忽略監聽的檔案夾,支援正規表達式;
  11. max_memory_restart  最大記憶體限制數,超出自動重新開機;
  12. env  環境變量,object類型,如{"NODE_ENV":"production", "ID": "42"};
  13. log_date_format  指定日志日期格式,如YYYY-MM-DD HH:mm:ss;
  14. error_file  記錄标準錯誤流,$HOME/.pm2/logs/XXXerr.log),代碼錯誤可在此檔案查找;
  15. out_file  記錄标準輸出流,$HOME/.pm2/logs/XXXout.log),如應用列印大量的标準輸出,會導緻pm2日志過大;
  16. min_uptime  應用運作少于時間被認為是異常啟動;
  17. max_restarts  最大異常重新開機次數,即小于min_uptime運作時間重新開機次數;
  18. autorestart  預設為true, 發生異常的情況下自動重新開機;
  19. cron_restart  crontab時間格式重新開機應用,目前隻支援cluster模式;
  20. force  預設false,如果true,可以重複啟動一個腳本。pm2不建議這麼做;
  21. restart_delay  異常重新開機情況下,延時重新開機時間;

上面内容比較枯燥無味,下面是結合自己實踐中遇到的一些坑做的思考總結。

四,fork與cluster啟動模式

pm2啟動程序的支援兩種模式:fork與cluster,對于了解node的人知道,node的多程序程式設計api: child_process.fork與cluster。關于pm2的fork與cluster兩者的本質差別,個人認為就是node API的child_process.fork與cluster的差別,stackoverflow有關于這個問題的讨論  http://stackoverflow.com/questions/346****35/cluster-and-fork-mode-difference-in-pm2。下面做個粗淺的歸納:

  1. cluster是fork的派生,cluster支援所有cluster擁有的特性;
  2. fork不支援socket位址端口複用,cluster支援位址端口複用。因為隻有node的cluster子產品支援socket選項SO_REUSEADDR;
  3. fork不可以啟動多個執行個體程序,cluster可以啟動多個執行個體。但node的child_process.fork是可以實作啟動多個程序的,但是為什麼沒有實作呢?就個人了解,node多為提供網絡服務,啟動多個執行個體需要位址端口複用,此時便可使用cluster模式實作,但fork模式并不支援位址端口複用,多執行個體程序啟動會産生異常錯誤。但對于常駐任務腳本而言,不需要提供網絡服務,此時多程序啟動可以實作,同時也提高了任務處理效率。對于上述需求,可以兩種方式實作,一是配置app0,app1,app2方式啟動多個程序,二是通過應用執行個體自身調用child_process.fork多程序程式設計實作;
  4. pm2用法詳解+ecosystem.config
  5. fork模式可以應用于其他語言,如php,python,perl,ruby,bash,coffee, 而cluster隻能應用于node;
  6. fork不支援定時重新開機,cluster支援定時重新開機。定時重新開機也就是配置中的cron_restart配置項。github上面有作者關于fork模式下是否需要實作cron-like定時的讨論:

    ​​​https://github.com/Unitech/pm2/issues/496​​官網文檔注明說,fork模式的定時重新開機這個功能不久将實作,期待中吧... ...

五,pm2的監控

pm2的監控有兩種方式:

  1. cli方式監控

    pm2 monit是專門用來監控的指令,監控項包括cpu與記憶體

  2. pm2用法詳解+ecosystem.config
  3. 缺點monit展示内容太過粗糙,不夠詳細

    pm2 list展示目前所有pm2的管理項目

  4. pm2用法詳解+ecosystem.config
  5. 可以檢視出每個程序的運作狀态。

    如果需要更詳細的監控内容,對于cli而言一般都是可以實作的。

    這種監控方式的缺點:

    a. 不夠直覺,需要自己去執行指令并分析結果;

    b. 不便于多台伺服器的應用監控管理;

    由于這些缺點,就需要一種更好的方式去監控我們的應用

  6. keymetrics監控

    keymetrics監控是PM2的開發者的開發和維護的一款監控工具,可以嘗試一下,安裝配置非常容易,我也隻是粗淺的嘗試了一下,可以參考

    ​​​http://cnodejs.org/topic/565****00ad12df5d4e050b56​​​本人對監控研究不多,這裡的監控主體是應用程序,非伺服器,就隻說說我比較喜歡的幾個功能:

    a. 利于多伺服器監控管理;

    b. 代碼異常,可以看出程式長期運作中的穩定性;

    c. 支援應用基本的啟動,重新開機與停止等功能;

    pm2用法詳解+ecosystem.config

    但是,keymetrics是一款商業版的監控軟體,免費版功能有限,且隻有兩台伺服器的免費配額,這款軟體的服務端非自建,采用的是将應用監控資料定時上抛第三平台,對于有着衆多伺服器的公司而言費用昂貴,而且伺服器與應用服務程序等狀态資訊是敏感性資料,接入到第三方平台中無法接受。當然,如果是伺服器數量有限,能夠支付昂貴的使用費用,無敏感資料等場景的話,推薦使用Keymetrics,畢竟是PM2的開發者的開發和維護,功能特性很豐富。

    鑒于以上問題,國内牛人開發了一款類似的免費工具,本人沒有研究過,名字很有趣: pm2.5。連結位址

    http://www.open-open.com/lib/view/open145****0105.html

    關于監控,本人經驗不多,就不多妄言了

六,日志問題

日志系統對于任意應用而言,通常都是必不可少的一個輔助功能。pm2的相關檔案預設存放于$HOME/.pm2/目錄下,其日志主要有兩類:

pm2用法詳解+ecosystem.config

 a. pm2自身的日志,存放于$HOME/.pm2/pm2.log;

 b. pm2所管理的應用的日志,存放于$HOME/.pm2/logs/目錄下,标準誰出日志存放于${APP_NAME}_out.log,标準錯誤日志存放于${APP_NAME}_error.log;

這裡之是以把日志單獨說明一下是因為,如果程式開發不嚴謹,為了調試程式,導緻應用産生大量标準輸出,使伺服器本身記錄大量的日志,導緻服務磁盤滿載問題。一般而言,pm2管理的應用本身都有自己日志系統,是以對于這種不必要的輸出内容需禁用日志,重定向到/dev/null。

與crontab比較,也有類似情況,crontab自身日志,與其管理的應用本身的輸出。應用腳本輸出一定需要重定向到/dev/null,因為該輸出内容會以郵件的形式發送給使用者,内容存儲在郵件檔案,會産生意向不到的結果,或會導緻腳本壓根不被執行;

七,穩定運作建議

PM2是一款非常優秀的Node程序管理工具,它有着豐富的特性:能夠充分利用多核CPU且能夠負載均衡、能夠幫助應用在崩潰後、指定時間(cluster model)和超出最大記憶體限制等情況下實作自動重新開機。

個人幾點看法保證常駐應用程序穩定運作:

1. 定時重新開機,應用程序運作時間久了或許總會産生一些意料之外的問題,定時可以規避一些不可測的情況;

2. 最大記憶體限制,根據觀察設定合理記憶體限制,保證應用異常運作;

3. 合理min_uptime,min_uptime是應用正常啟動的最小持續運作時長,超出此時間則被判定為異常啟動;

4. 設定異常重新開機延時restart_delay,對于異常情況導緻應用停止,設定異常重新開機延遲可防止應用在不可測情況下不斷重新開機的導緻重新開機次數過多等問題;

5. 設定異常重新開機次數,如果應用不斷異常重新開機,并超過一定的限制次數,說明此時的環境長時間處于不可控狀态,伺服器異常。此時便可停止嘗試,發出錯誤警告通知等。

繼續閱讀