node中的線程進程及pm2的使用node
進程 process是系統進行資源分配和調度的基本單位,是操做系統結構的基礎,進程是線程的容器(來自百科)。進程是資源分配的最小單位。咱們啓動一個服務、運行一個實例,就是開一個服務進程shell
以下就是一個node進程:json
const http = require('http') const server = http.createServer(); server.listen(3000, ()=>{ console.log('進程id', process.pid) })
線程是操做系統可以進行運算調度的最小單位,首先咱們要清楚線程是隸屬於進程的,被包含於進程之中。一個線程只能隸屬於一個進程,可是一個進程是能夠擁有多個線程的。api
單線程就是一個進程只開一個線程併發
Javascript 就是屬於單線程,程序順序執行(這裏暫且不提JS異步),能夠想象一下隊列,前面一個執行完以後,後面才能夠執行,當你在使用單線程語言編碼時切勿有過多耗時的同步操做,不然線程會形成阻塞,致使後續響應沒法處理。你若是採用 Javascript 進行編碼時候,請儘量的利用Javascript異步操做的特性。app
const http = require('http') const fork = require('child_process').fork const server = http.createServer((req, res) =>{ if (req.url === '/demo') { const son = fork("./son.js") son.send('開啓一個子進程') // 當一個子進程使用 process.send() 發送消息時會觸發 ‘message’事件 son.on('message', ()=>{ son.kill() }) // 子進程監聽到錯誤退出終止 son.on('close', () =>{ son.kill() }) } }) server.listen(8086)
const cluster = require('cluster'); const os = require('os'); if (cluster.isMaster) { for (var i = 0, n = os.cpus().length; i < n; i += 1) { cluster.fork(); } } else { // 啓動程序 }
每次啓動 Node.js 程序都須要在命令窗口輸入命令 node app.js
才能啓動,但若是把命令窗口關閉則Node.js 程序服務就會馬上斷掉。當咱們這個 Node.js 服務意外崩潰了就不能自動重啓進程了。執行 node app.js 開啓一個服務進程以後,我還能夠在這個終端上作些別的事情,且不會相互影響,當出現問題能夠自動重啓。框架
第三方的進程守護框架,pm2 和 forever ,它們均可以實現進程守護,底層也都是經過上面講的 child_process 模塊和 cluster 模塊實現的異步
$ pm2 start app.js -i 4 # 後臺運行pm2,啓動4個app.js $ pm2 list # 顯示全部進程狀態 $ pm2 monit # 監視全部進程 $ pm2 logs # 顯示全部進程日誌 $ pm2 reload all/app_name # 0秒停機重載進程,會算在服務重啓的次數中,相似於平滑重啓 $ pm2 restart id/all/app_name # 會從新加載代碼,由於須要殺掉原有進程,因此服務會中斷 $ pm2 stop id/all/app_name # 中止指定名稱的進程,若是是一個名稱多進程,則一塊兒中止,不會釋放端口 $ pm2 delete id/all/app_name # 刪除指定名稱的進程,若是是一個名稱多進程,則一塊兒刪除,不會釋放端口 $ pm2 kill # 殺掉全部pm2進程並釋放資源,包含pm2自身,會釋放端口
經過json文件配置文件啓動服務高併發
{ "apps": { "name": "xbb", // 項目名 "script": "./bin/node", // 執行文件 "cwd": "./", // 根目錄 "watch": true, // 是否監聽文件變更而後重啓 "ignore_watch": [ // 不用監聽的文件 "node_modules", "logs" ], "exec_mode": "cluster_mode", // 應用啓動模式,支持fork和cluster模式 "instances": 4, // 應用啓動實例個數,僅在cluster模式有效 默認爲fork;或者 max "max_memory_restart": 8, // 最大內存限制數,超出自動重啓 "error_file": "./logs/app-err.log", // 錯誤日誌文件 "out_file": "./logs/app-out.log", // 正常日誌文件 "min_uptime": "60s", // 應用運行少於時間被認爲是異常啓動 "max_restarts": 30, // 最大異常重啓次數,即小於min_uptime運行時間重啓次數; "autorestart": true, // 默認爲true, 發生異常的狀況下自動重啓 "cron_restart": "", // crontab時間格式重啓應用,目前只支持cluster模式; "restart_delay": "60s" // 異常重啓狀況下,延時重啓時間 "env": { "NODE_ENV": "production", // 環境參數,當前指定爲生產環境 process.env.NODE_ENV "REMOTE_ADDR": "xbb" // process.env.REMOTE_ADDR }, "env_dev": { "NODE_ENV": "development", // 環境參數,當前指定爲開發環境 pm2 start app.js --env_dev "REMOTE_ADDR": "" }, "env_test": { // 環境參數,當前指定爲測試環境 pm2 start app.js --env_test "NODE_ENV": "test", "REMOTE_ADDR": "" } } }