對於後臺進程的管理,經常使用的工具是crontab,可用於兩種場景:定時任務和常駐腳本。關於常駐腳本,今天介紹一款更好用的工具:pm2,基於nodejs開發的進程管理器,適用於後臺常駐腳本管理,同時對node網絡應用有自建負載均衡功能。官方的說法,pm2 是一個帶有負載均衡功能的Node應用的進程管理器,我的認爲,並不許確,由於pm2支持多種語言,只是對於除node以外的其餘進程無負載均衡的能力。php
一,pm2特色:html
說一些pm2有哪些優勢好處呢?node
支持進程行爲配置 ,便可以經過配置,實現對pm2管理應用的一些基礎屬性更新修改,如應用名稱,啓動模式等;python
支持集羣模式,支持負載均衡,但因採用nodejs的cluster模塊實現,僅適用於nodejs進程;linux
支持source map,此項針對js, source map文件是js源文件的信息文件,裏面存儲着源文件的位置信息;git
支持熱重啓;github
支持部署工做流,pm2可依據測試環境和線上環境自動部署到不一樣的服務器,同時運行在不一樣配置下;web
支持監聽重啓,在文件更新等狀況下可實現進程自動重啓;正則表達式
支持linux的startup進程啓動,startup是指系統boot, 進程自啓動,如centos的chkconfig;編程
日誌管理,兩種日誌,pm2系統日誌與管理的進程日誌,默認會把進程的控制檯輸出記錄到日誌中;
命令自動補全功能,我的感受這個功能意義不大,並且嘗試了一下,沒有原生的linux命令自動補全反應敏捷;
監控功能,pm2 monit監控cpu和memory使用狀況,keymetrics監控更爲詳細;
支持開發調試模式,非後臺運行,pm2-dev start <appName>;
支持pm2模塊開發,實現pm2的功能擴展;
keymetrics監控,比pm2 monit監控更爲詳細友好,經過web頁面展現;
最大內存重啓,設置最大內存限制,超過限制自動重啓;
編程API,提供API供開發者經過編程方式靈活管理進程;
以上簡要概述了pm2進程管理工具的特色。
二,pm2經常使用命令
經常使用命令一般都是比較簡單。下面列舉一些pm2經常使用的管理命令
pm2 start <script_file|config_file> [options] 啓動指定應用,如pm2 start index.js --name httpServer;
pm2 stop <appName> [options] 中止指定應用,如pm2 stop httpServer;
pm2 reload|restart <appName> [options] 重啓指定應用,如pm2 restart httpServer;
pm2 show <appName> [options] 顯示指定應用詳情,如pm2 show httpServer;
pm2 delete <appName> [options] 刪除指定應用,如pm2 delete httpServer,若是修改應用配置行爲,最好先刪除應用後,從新啓動方纔生效,如修改腳本入口文件;
pm2 kill 殺掉pm2管理的全部進程;
pm2 logs <appName> 查看指定應用的日誌,即標準輸出和標準錯誤;
pm2 monit 監控各個應用進程cpu和memory使用狀況;
三,pm2經常使用配置
pm2 配置方式
命令行方式
pm2 start index.js --name HttpServer --interpreter node
此處經過命令的選項配置應用名稱爲httpServer,index.js腳本文件解釋器爲node,更多選項可查看pm2 --help獲取;
配置文件方式
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" }]}
配置項
name 應用進程名稱;
script 啓動腳本路徑;
cwd 應用啓動的路徑,關於script與cwd的區別舉例說明:在/home/polo/目錄下運行/data/release/node/index.js,此處script爲/data/release/node/index.js,cwd爲/home/polo/;
args 傳遞給腳本的參數;
interpreter 指定的腳本解釋器;
interpreter_args 傳遞給解釋器的參數;
instances 應用啓動實例個數,僅在cluster模式有效,默認爲fork;
exec_mode 應用啓動模式,支持fork和cluster模式;
watch 監聽重啓,啓用狀況下,文件夾或子文件夾下變化應用自動重啓;
ignore_watch 忽略監聽的文件夾,支持正則表達式;
max_memory_restart 最大內存限制數,超出自動重啓;
env 環境變量,object類型,如{"NODE_ENV":"production", "ID": "42"};
log_date_format 指定日誌日期格式,如YYYY-MM-DD HH:mm:ss;
error_file 記錄標準錯誤流,$HOME/.pm2/logs/XXXerr.log),代碼錯誤可在此文件查找;
out_file 記錄標準輸出流,$HOME/.pm2/logs/XXXout.log),如應用打印大量的標準輸出,會致使pm2日誌過大;
min_uptime 應用運行少於時間被認爲是異常啓動;
max_restarts 最大異常重啓次數,即小於min_uptime運行時間重啓次數;
autorestart 默認爲true, 發生異常的狀況下自動重啓;
cron_restart crontab時間格式重啓應用,目前只支持cluster模式;
force 默認false,若是true,能夠重複啓動一個腳本。pm2不建議這麼作;
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。下面作個粗淺的概括:
cluster是fork的派生,cluster支持全部cluster擁有的特性;
fork不支持socket地址端口複用,cluster支持地址端口複用。由於只有node的cluster模塊支持socket選項SO_REUSEADDR;
fork不能夠啓動多個實例進程,cluster能夠啓動多個實例。但node的child_process.fork是能夠實現啓動多個進程的,可是爲何沒有實現呢?就我的理解,node多爲提供網絡服務,啓動多個實例須要地址端口複用,此時即可使用cluster模式實現,但fork模式並不支持地址端口複用,多實例進程啓動會產生異常錯誤。但對於常駐任務腳本而言,不須要提供網絡服務,此時多進程啓動能夠實現,同時也提升了任務處理效率。對於上述需求,能夠兩種方式實現,一是配置app0,app1,app2方式啓動多個進程,二是經過應用實例自身調用child_process.fork多進程編程實現;
fork模式能夠應用於其餘語言,如php,python,perl,ruby,bash,coffee, 而cluster只能應用於node;
fork不支持定時重啓,cluster支持定時重啓。定時重啓也就是配置中的cron_restart配置項。github上面有做者關於fork模式下是否須要實現cron-like定時的討論:
https://github.com/Unitech/pm2/issues/496
官網文檔註明說,fork模式的定時重啓這個功能不久將實現,期待中吧... ...
五,pm2的監控
pm2的監控有兩種方式:
cli方式監控
pm2 monit是專門用來監控的命令,監控項包括cpu與內存
缺點monit展現內容太過粗糙,不夠詳細
pm2 list展現當前全部pm2的管理項目
能夠查看出每一個進程的運行狀態。
若是須要更詳細的監控內容,對於cli而言通常都是能夠實現的。
這種監控方式的缺點:
a. 不夠直觀,須要本身去執行命令並分析結果;
b. 不便於多臺服務器的應用監控管理;
因爲這些缺點,就須要一種更好的方式去監控咱們的應用
keymetrics監控
keymetrics監控是PM2的開發者的開發和維護的一款監控工具,能夠嘗試一下,安裝配置很是容易,我也只是粗淺的嘗試了一下,能夠參考
http://cnodejs.org/topic/565****00ad12df5d4e050b56
本人對監控研究很少,這裏的監控主體是應用進程,非服務器,就只說說我比較喜歡的幾個功能:
a. 利於多服務器監控管理;
b. 代碼異常,能夠看出程序長期運行中的穩定性;
c. 支持應用基本的啓動,重啓與中止等功能;
可是,keymetrics是一款商業版的監控軟件,免費版功能有限,且只有兩臺服務器的免費配額,這款軟件的服務端非自建,採用的是將應用監控數據定時上拋第三平臺,對於有着衆多服務器的公司而言費用昂貴,並且服務器與應用服務進程等狀態信息是敏感性數據,接入到第三方平臺中沒法接受。固然,若是是服務器數量有限,可以支付昂貴的使用費用,無敏感數據等場景的話,推薦使用Keymetrics,畢竟是PM2的開發者的開發和維護,功能特性很豐富。
鑑於以上問題,國內牛人開發了一款相似的免費工具,本人沒有研究過,名字頗有趣: pm2.5。連接地址
http://www.open-open.com/lib/view/open145****0105.html
關於監控,本人經驗很少,就很少妄言了
六,日誌問題
日誌系統對於任意應用而言,一般都是必不可少的一個輔助功能。pm2的相關文件默認存放於$HOME/.pm2/目錄下,其日誌主要有兩類:
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. 設置異常重啓次數,若是應用不斷異常重啓,並超過必定的限制次數,說明此時的環境長時間處於不可控狀態,服務器異常。此時即可中止嘗試,發出錯誤警告通知等。