對于后臺進程的管理,常用的工具是crontab,可用于兩種場景:定時任務(wù)和常駐腳本。關(guān)于常駐腳本,今天介紹一款更好用的工具:pm2,基于nodejs開發(fā)的進程管理器,適用于后臺常駐腳本管理,同時對node網(wǎng)絡(luò)應(yīng)用有自建負載均衡功能。官方的說法,pm2 是一個帶有負載均衡功能的Node應(yīng)用的進程管理器,個人認為,并不準確,因為pm2支持多種語言,只是對于除node之外的其他進程無負載均衡的能力。
一,pm2特點:
說一些pm2有哪些優(yōu)點好處呢?
- 支持進程行為配置 ,即可以通過配置,實現(xiàn)對pm2管理應(yīng)用的一些基礎(chǔ)屬性更新修改,如應(yīng)用名稱,啟動模式等;
- 支持集群模式,支持負載均衡,但因采用nodejs的cluster模塊實現(xiàn),僅適用于nodejs進程;
- 支持source map,此項針對js, source map文件是js源文件的信息文件,里面存儲著源文件的位置信息;
- 支持熱重啟;
- 支持部署工作流,pm2可依據(jù)測試環(huán)境和線上環(huán)境自動部署到不同的服務(wù)器,同時運行在不同配置下;
- 支持監(jiān)聽重啟,在文件更新等情況下可實現(xiàn)進程自動重啟;
- 支持linux的startup進程啟動,startup是指系統(tǒng)boot, 進程自啟動,如centos的chkconfig;
- 日志管理,兩種日志,pm2系統(tǒng)日志與管理的進程日志,默認會把進程的控制臺輸出記錄到日志中;
- 命令自動補全功能,個人感覺這個功能意義不大,而且嘗試了一下,沒有原生的linux命令自動補全反應(yīng)敏捷;
- 監(jiān)控功能,pm2 monit監(jiān)控cpu和memory使用情況,keymetrics監(jiān)控更為詳細;
- 支持開發(fā)調(diào)試模式,非后臺運行,pm2-dev start <appName>;
- 支持pm2模塊開發(fā),實現(xiàn)pm2的功能擴展;
- keymetrics監(jiān)控,比pm2 monit監(jiān)控更為詳細友好,通過web頁面展示;
- 最大內(nèi)存重啟,設(shè)置最大內(nèi)存限制,超過限制自動重啟;
- 編程API,提供API供開發(fā)者通過編程方式靈活管理進程;
以上簡要概述了pm2進程管理工具的特點。
二,pm2常用命令
常用命令通常都是比較簡單。下面列舉一些pm2常用的管理命令
- pm2 start <script_file|config_file> [options] 啟動指定應(yīng)用,如pm2 start index.js --name httpServer;
- pm2 stop <appName> [options] 停止指定應(yīng)用,如pm2 stop httpServer;
- pm2 reload|restart <appName> [options] 重啟指定應(yīng)用,如pm2 restart httpServer;
- pm2 show <appName> [options] 顯示指定應(yīng)用詳情,如pm2 show httpServer;
- pm2 delete <appName> [options] 刪除指定應(yīng)用,如pm2 delete httpServer,如果修改應(yīng)用配置行為,最好先刪除應(yīng)用后,重新啟動方才生效,如修改腳本入口文件;
- pm2 kill 殺掉pm2管理的所有進程;
- pm2 logs <appName> 查看指定應(yīng)用的日志,即標準輸出和標準錯誤;
- pm2 monit 監(jiān)控各個應(yīng)用進程cpu和memory使用情況;
三,pm2常用配置
pm2 配置方式
- 命令行方式pm2 start index.js --name HttpServer --interpreter node此處通過命令的選項配置應(yīng)用名稱為httpServer,index.js腳本文件解釋器為node,更多選項可查看pm2 --help獲?。?/li>
- 配置文件方式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 應(yīng)用進程名稱;
- script 啟動腳本路徑;
- cwd 應(yīng)用啟動的路徑,關(guān)于script與cwd的區(qū)別舉例說明:在/home/polo/目錄下運行/data/release/node/index.js,此處script為/data/release/node/index.js,cwd為/home/polo/;
- args 傳遞給腳本的參數(shù);
- interpreter 指定的腳本解釋器;
- interpreter_args 傳遞給解釋器的參數(shù);
- instances 應(yīng)用啟動實例個數(shù),僅在cluster模式有效,默認為fork;
- exec_mode 應(yīng)用啟動模式,支持fork和cluster模式;
- watch 監(jiān)聽重啟,啟用情況下,文件夾或子文件夾下變化應(yīng)用自動重啟;
- ignore_watch 忽略監(jiān)聽的文件夾,支持正則表達式;
- max_memory_restart 最大內(nèi)存限制數(shù),超出自動重啟;
- env 環(huán)境變量,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),如應(yīng)用打印大量的標準輸出,會導(dǎo)致pm2日志過大;
- min_uptime 應(yīng)用運行少于時間被認為是異常啟動;
- max_restarts 最大異常重啟次數(shù),即小于min_uptime運行時間重啟次數(shù);
- autorestart 默認為true, 發(fā)生異常的情況下自動重啟;
- cron_restart crontab時間格式重啟應(yīng)用,目前只支持cluster模式;
- force 默認false,如果true,可以重復(fù)啟動一個腳本。pm2不建議這么做;
- restart_delay 異常重啟情況下,延時重啟時間;
上面內(nèi)容比較枯燥無味,下面是結(jié)合自己實踐中遇到的一些坑做的思考總結(jié)。
四,fork與cluster啟動模式
pm2啟動進程的支持兩種模式:fork與cluster,對于了解node的人知道,node的多進程編程api: child_process.fork與cluster。關(guān)于pm2的fork與cluster兩者的本質(zhì)區(qū)別,個人認為就是node API的child_process.fork與cluster的區(qū)別,stackoverflow有關(guān)于這個問題的討論 http://stackoverflow.com/questions/346****35/cluster-and-fork-mode-difference-in-pm2。下面做個粗淺的歸納:
- cluster是fork的派生,cluster支持所有cluster擁有的特性;
- fork不支持socket地址端口復(fù)用,cluster支持地址端口復(fù)用。因為只有node的cluster模塊支持socket選項SO_REUSEADDR;
- fork不可以啟動多個實例進程,cluster可以啟動多個實例。但node的child_process.fork是可以實現(xiàn)啟動多個進程的,但是為什么沒有實現(xiàn)呢?就個人理解,node多為提供網(wǎng)絡(luò)服務(wù),啟動多個實例需要地址端口復(fù)用,此時便可使用cluster模式實現(xiàn),但fork模式并不支持地址端口復(fù)用,多實例進程啟動會產(chǎn)生異常錯誤。但對于常駐任務(wù)腳本而言,不需要提供網(wǎng)絡(luò)服務(wù),此時多進程啟動可以實現(xiàn),同時也提高了任務(wù)處理效率。對于上述需求,可以兩種方式實現(xiàn),一是配置app0,app1,app2方式啟動多個進程,二是通過應(yīng)用實例自身調(diào)用child_process.fork多進程編程實現(xiàn);
- fork模式可以應(yīng)用于其他語言,如php,python,perl,ruby,bash,coffee, 而cluster只能應(yīng)用于node;
- fork不支持定時重啟,cluster支持定時重啟。定時重啟也就是配置中的cron_restart配置項。github上面有作者關(guān)于fork模式下是否需要實現(xiàn)cron-like定時的討論:https://github.com/Unitech/pm2/issues/496官網(wǎng)文檔注明說,fork模式的定時重啟這個功能不久將實現(xiàn),期待中吧... ...
五,pm2的監(jiān)控
pm2的監(jiān)控有兩種方式:
- cli方式監(jiān)控pm2 monit是專門用來監(jiān)控的命令,監(jiān)控項包括cpu與內(nèi)存
缺點monit展示內(nèi)容太過粗糙,不夠詳細
pm2 list展示當(dāng)前所有pm2的管理項目
可以查看出每個進程的運行狀態(tài)。
如果需要更詳細的監(jiān)控內(nèi)容,對于cli而言一般都是可以實現(xiàn)的。
這種監(jiān)控方式的缺點:
a. 不夠直觀,需要自己去執(zhí)行命令并分析結(jié)果;
b. 不便于多臺服務(wù)器的應(yīng)用監(jiān)控管理;
由于這些缺點,就需要一種更好的方式去監(jiān)控我們的應(yīng)用
keymetrics監(jiān)控
keymetrics監(jiān)控是PM2的開發(fā)者的開發(fā)和維護的一款監(jiān)控工具,可以嘗試一下,安裝配置非常容易,我也只是粗淺的嘗試了一下,可以參考
http://cnodejs.org/topic/565****00ad12df5d4e050b56
本人對監(jiān)控研究不多,這里的監(jiān)控主體是應(yīng)用進程,非服務(wù)器,就只說說我比較喜歡的幾個功能:
a. 利于多服務(wù)器監(jiān)控管理;
b. 代碼異常,可以看出程序長期運行中的穩(wěn)定性;
c. 支持應(yīng)用基本的啟動,重啟與停止等功能;
但是,keymetrics是一款商業(yè)版的監(jiān)控軟件,免費版功能有限,且只有兩臺服務(wù)器的免費配額,這款軟件的服務(wù)端非自建,采用的是將應(yīng)用監(jiān)控數(shù)據(jù)定時上拋第三平臺,對于有著眾多服務(wù)器的公司而言費用昂貴,而且服務(wù)器與應(yīng)用服務(wù)進程等狀態(tài)信息是敏感性數(shù)據(jù),接入到第三方平臺中無法接受。當(dāng)然,如果是服務(wù)器數(shù)量有限,能夠支付昂貴的使用費用,無敏感數(shù)據(jù)等場景的話,推薦使用Keymetrics,畢竟是PM2的開發(fā)者的開發(fā)和維護,功能特性很豐富。
鑒于以上問題,國內(nèi)牛人開發(fā)了一款類似的免費工具,本人沒有研究過,名字很有趣: pm2.5。鏈接地址
http://www.open-open.com/lib/view/open145****0105.html
關(guān)于監(jiān)控,本人經(jīng)驗不多,就不多妄言了
六,日志問題
日志系統(tǒng)對于任意應(yīng)用而言,通常都是必不可少的一個輔助功能。pm2的相關(guān)文件默認存放于$HOME/.pm2/目錄下,其日志主要有兩類:
a. pm2自身的日志,存放于$HOME/.pm2/pm2.log;
b. pm2所管理的應(yīng)用的日志,存放于$HOME/.pm2/logs/目錄下,標準誰出日志存放于${APP_NAME}_out.log,標準錯誤日志存放于${APP_NAME}_error.log;
這里之所以把日志單獨說明一下是因為,如果程序開發(fā)不嚴謹,為了調(diào)試程序,導(dǎo)致應(yīng)用產(chǎn)生大量標準輸出,使服務(wù)器本身記錄大量的日志,導(dǎo)致服務(wù)磁盤滿載問題。一般而言,pm2管理的應(yīng)用本身都有自己日志系統(tǒng),所以對于這種不必要的輸出內(nèi)容需禁用日志,重定向到/dev/null。
與crontab比較,也有類似情況,crontab自身日志,與其管理的應(yīng)用本身的輸出。應(yīng)用腳本輸出一定需要重定向到/dev/null,因為該輸出內(nèi)容會以郵件的形式發(fā)送給用戶,內(nèi)容存儲在郵件文件,會產(chǎn)生意向不到的結(jié)果,或會導(dǎo)致腳本壓根不被執(zhí)行;
七,穩(wěn)定運行建議
PM2是一款非常優(yōu)秀的Node進程管理工具,它有著豐富的特性:能夠充分利用多核CPU且能夠負載均衡、能夠幫助應(yīng)用在崩潰后、指定時間(cluster model)和超出最大內(nèi)存限制等情況下實現(xiàn)自動重啟。
個人幾點看法保證常駐應(yīng)用進程穩(wěn)定運行:
1. 定時重啟,應(yīng)用進程運行時間久了或許總會產(chǎn)生一些意料之外的問題,定時可以規(guī)避一些不可測的情況;
2. 最大內(nèi)存限制,根據(jù)觀察設(shè)定合理內(nèi)存限制,保證應(yīng)用異常運行;
3. 合理min_uptime,min_uptime是應(yīng)用正常啟動的最小持續(xù)運行時長,超出此時間則被判定為異常啟動;
4. 設(shè)定異常重啟延時restart_delay,對于異常情況導(dǎo)致應(yīng)用停止,設(shè)定異常重啟延遲可防止應(yīng)用在不可測情況下不斷重啟的導(dǎo)致重啟次數(shù)過多等問題;
5. 設(shè)置異常重啟次數(shù),如果應(yīng)用不斷異常重啟,并超過一定的限制次數(shù),說明此時的環(huán)境長時間處于不可控狀態(tài),服務(wù)器異常。此時便可停止嘗試,發(fā)出錯誤警告通知等。