溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

nodejs中怎么實現多進程

發布時間:2021-06-22 15:09:52 來源:億速云 閱讀:387 作者:Leah 欄目:大數據

今天就跟大家聊聊有關nodejs中怎么實現多進程,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

為什么要使用多進程
  • nodjes單線程,在處理http請求的時候一個錯誤都會導致整個進程的退出,這是災難級的;

多進程和多線程介紹
  • 進程是資源分配的最小單位,線程是CPU調度的最小單位

  • 進程--資源分配最小單位,線程--程序咨詢最小單位

  • 線程是進程的執行流,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位,一個進程由幾個線程組成,線程與同屬一個進程的其他線程共享進程所擁有的全部資源。

一個進程下面的線程是可以去通信的,共享資源

  • 進程由獨立的地址空間,一個進程崩潰后,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑,線程有自己的堆棧和局部變量,但線程沒有嘟嘟的地址空間,一個線程死掉等于整個進程死掉;

  • 谷歌瀏覽器

    • 進程:一個tab就是一個進程

    • 線程:一個tab又由多個線程組成,渲染線程,js執行線程,垃圾回收,service worker等

  • node服務

    • 主線程:獲取代碼,編譯執行

    • 編譯線程:主線程執行的時候,可以優化代碼(v8引擎)

    • Profiler線程:記錄哪些方法耗時,為優化提供支持

    • 其他線程:用于垃圾回收清除工作,因為多個線程,所以可以并行清除

    • ab是Apache自帶的壓力測試工具

    • ab -1000 -c20 '192.168.31.25:8000/'

    • 進程:監聽某個端口的http服務

    • 線程:http服務由多個線程組成,比如:

多線程和多線程的選擇

多進程和多線程一般可以結合起來使用

  • 多進程:穩定,安全

  • 多線程:快

對比維度多進程多線程總結
數據共享、同步數據共享復雜,需要用IPC;數據是分開的,同步簡單因為共享進程數據,數據共享簡單,但也是因為這個導致同步復雜各有優勢
內存、cpu占用內存多,切換負責,cpu利用率低占用內存少,切換簡單,cpu利用率高線程占優
創建銷毀、切換創建銷毀復雜,速度慢創建銷毀簡單,速度很快線程占優
編程、調試編程簡單,調試簡單編程復雜、調試復雜進程占優
可靠性進程間不會相互影響一個線程掛掉將導致整個進程掛掉進程占優
分布式適應于多核、多機分布式;如果一臺機器不夠,擴展到多臺機器比較簡單適應于多核分布式進程占優
  • 1.需要頻繁發創建銷毀的優先使用線程

    • 常見Web服務器,來一個連接創建一個線程,斷了就銷毀線程,要是用進程,創建和銷毀的代價都是難以承受的

  • 2.需要進行大量計算的優先使用線程

    • 所謂大量計算,就是要耗費很多cpu,切換頻繁了,這種情況下線程是適合的;常見:圖像處理,算法處理;

  • 強相關的用線程處理,弱相關的用進程處理

    • 如:消息收發,消息處理;

    • 消息收發和消息處理屬于若相關任務,分進程設計

    • 消息處理里面可能又分消息解碼、業務處理,關聯性強,分線程設計;

  • 可能要擴展到多機器分布用進程,多核分布用線程

  • 都可滿足的情況,用擅長的

nodejs多線程
  • worker_threads模塊

創建多進程

利用cluster開啟多進程

  • ab是apache自帶的壓力測試工具

  • ab -n1000 -c20 '192.168.31.25:8000/'

const cluster = require('cluster'); // 多進程
const http = require('http');
const numCpus = require('os').cpus().length; // 獲取cpu的核數
if(cluster.isMaster){ // 是否是主線程
    for(var i = 0; i < numCpus; i++){
        cluster.fork() // 開啟子線程
    cluster.on('exit', function(worker, code ,signal){
// 監測哪個進程掛掉
        console.log('worker'+worker.process.pid+'died')
    })
    }
} else {
  http.createServer((req,res) =>{
    res.writeHead(200);
    res.end('hello world');
  }).listen(8000)  
}
多進程和單進程性能對比

多進程的性能要明顯好于單進程

  • ab是apache自帶的壓力測試工具,推薦使用mac

  • ab -n1000 -c20 '192.168.31.25:8000/'

  • n 請求數量

  • c 并發數量

nodejs調試工具
  • vscode的.vscode下面配置 launch.json; 調試 修改program 工作目錄

cluster 相關API

Process進程,child_process子進程,Cluster集群

process 進程

process對象是Node的一個全局對象,提供當前Node進程的信息,它也可以在腳本的任意位置使用,不必通過require獲??;

屬性

  1. process.argv屬性,返回一個數組,包含了node進程時的命令行參數;

  2. process.env返回包含用戶環境信息的對象,可以在腳本中心對這個隊形進行curd操作;

  3. process.pid返回當前進程的進程號

  4. process.platform 返回當前的操作系統

  5. process.version 返回當前node的版本

方法

  1. process.cwd() 返回node.js進程當前的工作目錄

  2. proces.chdir() 變更node.js進程的工作目錄

  3. process.nextTick() 將任務放到當前時間循環的尾部,添加到next tick隊列,一旦當前時間輪詢隊列的任我全部完成,在next tick隊列的所有callback會被依次調用;

  4. process.exit() 退出當前進程時觸發;很多時候是不需要的;

  5. process.kill(pid[,signal]) 給指定的進程發信號,包括但不限于結束進程;

事件

  1. beforeExit事件,在node清空了EventLoop之后,再沒有任何待處理任務時觸發,可以在這里再部署一些任務,使得node進程不退出,顯示的終止程序時(process.exit()),不會觸發;

  2. exit事件,當前進程退出時觸發,回調函數中只允許同步操作,因為執行完回調后,進程全部退出;

  3. uncaughtException事件,兜底方案,當前進程拋出一個沒有捕獲的異步錯誤時觸發,可以用它在進程結束前進行一些已分配資源的同步清理操作,嘗試用它來恢復應用的正常運行的操作是不安全的;

  4. warning事件;任何nodejs發出的警告都會觸發此事件;

bbb()  
// 這里會直接報錯,因為js是單線程的,
// uncaughtException專門是捕捉異步代碼錯誤,特別是http
process.on('uncaughtException', (err) =>{
    console.log(err)
})
const http = require('http');
http.createServer((req, res) => {
    ccc()
}).listen(8000, () => {
    console.log(`server is runing on 8000`)
})

process.on('uncaghtException', (err) => { 
// 這里會捕獲ccc的異步錯誤s
    console.log('發生錯誤',err)
})
child_process

node中用于創建子進程的模塊,cluster就是基于child_process模塊封裝的;

  1. child_process.exec()

  • 執行異步命令,運行結束后調用回調函數,或監聽事件輸出;

  • 參數可以隨便輸入,安全性不高

  • 方法2在監聽到data事件以后, 可以一邊讀取一邊接收結果,不用等子進程結束;如果子進程運行時間較長,或者持續運行,建議使用方法2;

const exec = require('child_process').exec;

// 1. 通過回調的方式接收結果
// exec('ls', (err, stdout, stderr) => {
//   // 在node中,容錯處理和業務代碼一樣重要;
//   // 因為js是單線程,一旦發生錯誤,后面代碼就不會執行
//   if (err) {
//     console.log('stderr', stderr);
//   }
//   console.log('err', err);
//   console.log('stdout', stdout);
// });

// 由于標準輸出和標準錯誤都是流對象(stream),可以監聽data事件
// 2. 通過流的方式返回結果,
// 可以一邊讀取一邊接收結果,不用等所有文件讀取完
var child = exec('lss');
child.stdout.on('data', data => {
  console.log(data);
});
// 發生錯誤
child.stderr.on('data', err => {
  console.log('發生錯誤了', err);
});

console.log(111)
  1. child_progress.execSync() 同步方法

var execSync('child_progress');
var path = '../'
var child = execSync(`ls ${path} \ rm rf`); //  這樣會刪除此文件夾的上一級目錄的所有文件
console.log(child.toString());
  1. execFile()

  • 直接執行特定的程序shell,參數作為數組傳入,不會被bash解釋,因此具有較高的安全性;

  • 會自動過濾一些敏感的字符串,如:'\ ;'

const { execFile } = require('child_progress')
execFile('ls', ['-c'], (err, stdout, stderr) => {
    console.log('stdout', stdout)
})
  1. child_process.spawn()

  • spawn 創建一個子進程來執行特定的shell,用法和execFile 類似,但是沒有回調函數,只能通過監聽事件來獲取運行結果,它屬于異步執行,適用于子進程長時間運行的情況;

  • spawn 返回的結果是buffer,需要轉成utf8;

const { spawn } = require('child_process');
let child = spawn('ls', ['-c']);
child.stdout.on('data', data => {
  console.log('data', data.toString('utf8'));
});
  1. child_process.fork()

  • child_process.fork() 會創建一個子進程,執行node腳本,

  • child_process.fork('./child.js') 相當于 child_process.spawn('node', ['./child.js']);

  • 與child_process.spawn()方法不同的是,child_process.fork()方法會在父進程和子進程之間建立一個通信管道pipe,用于進程之間的通信,也是IPC通信的基礎;

main.js

const child_process = require('child_process');
const path = require('path');
var child = child_process.fork(path.resolve(__dirname, './child.js'));
child.on('message', data => {
  console.log('父接收到子消息:', data);
});
child.send('父親send', data => {
  console.log('父親說:為父給你發消息了');
});

child.js

process.on('message', data => {
  console.log('兒子接收到父親消息:', data);
});

process.send('兒子send', data => {
  console.log('兒子對父親說:hello ');
});

看完上述內容,你們對nodejs中怎么實現多進程有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女