溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

node中cluster集群的作用是什么

發(fā)布時(shí)間:2021-01-16 10:53:51 來(lái)源:億速云 閱讀:247 作者:Leah 欄目:web開發(fā)

node中cluster集群的作用是什么?相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

結(jié)論

雖然平常通過設(shè)置為CPU進(jìn)程數(shù)的工作進(jìn)程,但是可以超過這個(gè)數(shù),并且并不是主進(jìn)程先創(chuàng)建

if (cluster.isMaster) {
 // 循環(huán) fork 任務(wù) CPU i5-7300HQ 四核四進(jìn)程
 for (let i = 0; i < 6; i++) {
  cluster.fork()
 }
 console.log(chalk.green(`主進(jìn)程運(yùn)行在${process.pid}`))
} else {
 app.listen(1314) // export app 一個(gè) Koa 服務(wù)器的實(shí)例
 console.log(chalk.green(`子進(jìn)程運(yùn)行在${process.pid}`))
}
#子進(jìn)程運(yùn)行在17768
#子進(jìn)程運(yùn)行在5784
#子進(jìn)程運(yùn)行在11232
#子進(jìn)程運(yùn)行在7904
#主進(jìn)程運(yùn)行在12960
#子進(jìn)程運(yùn)行在4300
#子進(jìn)程運(yùn)行在16056

在主進(jìn)程中 cluster 表示主進(jìn)程(用于監(jiān)聽、發(fā)送事件), process 是本身的進(jìn)程,worker 表示子進(jìn)程,通過 cluster.workers 獲取

在子進(jìn)程中 process 表示子進(jìn)程(用于監(jiān)聽、發(fā)送事件),也可以通過 cluster.worker 表示當(dāng)前子進(jìn)程

cluster.worker.process 等價(jià)于 process(在子進(jìn)程中)

主進(jìn)程子進(jìn)程相互通信

node中cluster集群的作用是什么

  1. cluster 用于監(jiān)聽 process(child) 子進(jìn)程觸發(fā)的各種事件

  2. worker 在主進(jìn)程中獲取,用于和自身通信。當(dāng)子進(jìn)程觸發(fā)事件時(shí),會(huì)返回當(dāng)前的 worker 以及相關(guān)的信息到主進(jìn)程相應(yīng)的事件中

  3. process(parent) 主進(jìn)程本身的進(jìn)程實(shí)例,在通信過程中基本沒有用到

  4. process(child) 子進(jìn)程本身的實(shí)例,只能在子進(jìn)程獲取用于監(jiān)聽自身的事件

可見主進(jìn)程與子進(jìn)程通過這樣一個(gè)三角關(guān)系互相通信,其中 cluster 和 worker 是在主進(jìn)程中獲取的,process(child) 是子進(jìn)程。 cluster 通過操作 worker 通知子進(jìn)程,子進(jìn)程本身和 cluster 進(jìn)行通信。為什么要這樣設(shè)計(jì)呢?因?yàn)樽舆M(jìn)程會(huì)有多個(gè),只有通過 worker 才能選擇和哪個(gè)進(jìn)程通信

子進(jìn)程的調(diào)度策略 cluster.schedulingPolicy

調(diào)度策略,包括循環(huán)計(jì)數(shù)的 cluster.SCHED_RR,以及由操作系統(tǒng)決定的cluster.SCHED_NONE。 這是一個(gè)全局設(shè)置,當(dāng)?shù)谝粋€(gè)工作進(jìn)程被衍生或者調(diào)動(dòng)cluster.setupMaster()時(shí),都將第一時(shí)間生效。除Windows外的所有操作系統(tǒng)中,SCHED_RR都是默認(rèn)設(shè)置。只要libuv可以有效地分發(fā)IOCP handle,而不會(huì)導(dǎo)致嚴(yán)重的性能沖擊的話,Windows系統(tǒng)也會(huì)更改為SCHED_RR。cluster.schedulingPolicy 可以通過設(shè)置NODE_CLUSTER_SCHED_POLICY環(huán)境變量來(lái)實(shí)現(xiàn)。這個(gè)環(huán)境變量的有效值包括"rr" 和 "none"。

RR 即 Round-Robin 輪詢調(diào)度,即每個(gè)子進(jìn)程的獲取的事件的機(jī)會(huì)是均等的,這是除 windows以外默認(rèn)的。而 windows 下的調(diào)度策略很詭異,見下圖。目前并沒有相關(guān) API 可以設(shè)置調(diào)度策略的算法,node 只為我們提供了兩個(gè)值

node中cluster集群的作用是什么

進(jìn)程調(diào)度算法.png

測(cè)試數(shù)據(jù)為 1000次 并發(fā)請(qǐng)求,重復(fù)測(cè)試20次,在windows下的表現(xiàn)情況。可見 windows 的調(diào)度算法表現(xiàn)的雜亂無(wú)章。如果是 RR 算法四條進(jìn)程的調(diào)度應(yīng)該處于同一橫線上。暫時(shí)沒在本地搭建 linux 環(huán)境,有條件的同學(xué)可以協(xié)助測(cè)試一波。
cluster的調(diào)度算法目前至于系統(tǒng)有關(guān)

多進(jìn)程間的鑒權(quán)問題

注意:Node.js不支持路由邏輯。因此在設(shè)計(jì)應(yīng)用時(shí),不應(yīng)該過分依賴內(nèi)存數(shù)據(jù)對(duì)象(如sessions和login等)。由于各工作進(jìn)程是獨(dú)立的進(jìn)程,它們可以根據(jù)需要隨時(shí)關(guān)閉或重新生成,而不影響其他進(jìn)程的正常運(yùn)行。只要有存活的工作進(jìn)程,服務(wù)器就可以繼續(xù)處理連接。如果沒有存活的工作進(jìn)程,現(xiàn)有連接會(huì)丟失,新的連接也會(huì)被拒絕。Node.js不會(huì)自動(dòng)管理工作進(jìn)程的數(shù)量,而應(yīng)該由具體的應(yīng)用根據(jù)實(shí)際需要來(lái)管理進(jìn)程池。

文檔中已明確說(shuō)明了,每一個(gè)工作進(jìn)程都是獨(dú)立的,并且互相之間除了能夠進(jìn)行通信外,沒有辦法共享內(nèi)存。所以在設(shè)計(jì)鑒權(quán)的時(shí)候,有兩種方法

  1. 通過共有的主進(jìn)程存儲(chǔ)鑒權(quán)信息,每次前端提交帳號(hào)密碼,授權(quán)完成后,將 token 發(fā)送給主進(jìn)程,下次前臺(tái)查詢時(shí)先在主進(jìn)程獲取授權(quán)信息

  2. 通過統(tǒng)一的外部 redis 存取

兩種方法看來(lái)還是第二種好的不要太多,因此多進(jìn)程的環(huán)境下,應(yīng)該使用外部數(shù)據(jù)庫(kù)統(tǒng)一存儲(chǔ) token 信息

進(jìn)一步的子進(jìn)程間通信思考

雖然 node 中并沒有直接提供的進(jìn)程間通訊功能,但是我們可以通過主進(jìn)程相互協(xié)調(diào)進(jìn)程間的通訊功能,需要定義標(biāo)準(zhǔn)的通信格式,例如

interface cmd {
 type: string
 from: number
 to: number
 msg: any
}

這樣通過統(tǒng)一的格式,主進(jìn)程就可以識(shí)別來(lái)自各個(gè)進(jìn)程間的通信,起到進(jìn)程通信中樞的功能

egg.js 中 agent 的實(shí)現(xiàn)

+--------+     +-------+
        | Master |<-------->| Agent |
        +--------+     +-------+
        ^  ^  ^
        /  |   \
       /   |    \
      /    |     \
     v     v     v
+----------+  +----------+  +----------+
| Worker 1 |  | Worker 2 |  | Worker 3 |
+----------+  +----------+  +----------+

我們看到 egg 在多進(jìn)程模型之間實(shí)現(xiàn)了一個(gè) agent 進(jìn)程,這個(gè)進(jìn)程主要負(fù)責(zé)對(duì)整個(gè)系統(tǒng)的定期維護(hù)

說(shuō)到這里,Node.js 多進(jìn)程方案貌似已經(jīng)成型,這也是我們?cè)缙诰€上使用的方案。但后來(lái)我們發(fā)現(xiàn)有些工作其實(shí)不需要每個(gè) Worker 都去做,如果都做,一來(lái)是浪費(fèi)資源,更重要的是可能會(huì)導(dǎo)致多進(jìn)程間資源訪問沖突。舉個(gè)例子:生產(chǎn)環(huán)境的日志文件我們一般會(huì)按照日期進(jìn)行歸檔,在單進(jìn)程模型下這再簡(jiǎn)單不過了:

每天凌晨 0 點(diǎn),將當(dāng)前日志文件按照日期進(jìn)行重命名

銷毀以前的文件句柄,并創(chuàng)建新的日志文件繼續(xù)寫入

試想如果現(xiàn)在是 4 個(gè)進(jìn)程來(lái)做同樣的事情,是不是就亂套了。所以,對(duì)于這一類后臺(tái)運(yùn)行的邏輯,我們希望將它們放到一個(gè)單獨(dú)的進(jìn)程上去執(zhí)行,這個(gè)進(jìn)程就叫 Agent Worker,簡(jiǎn)稱 Agent。Agent 好比是 Master 給其他 Worker 請(qǐng)的一個(gè)『秘書』,它不對(duì)外提供服務(wù),只給 App Worker 打工,專門處理一些公共事務(wù)。

這樣我們可以指定一個(gè)進(jìn)程作為 agent 進(jìn)程,用于實(shí)現(xiàn)自己定義的事務(wù)。在 egg 中,主線程啟動(dòng)后 首先 fork agent進(jìn)程,當(dāng) agent 進(jìn)程啟動(dòng)完成后再啟動(dòng)具體的 worker 進(jìn)程。參照上面的代碼,相信這部分邏輯現(xiàn)在也不難實(shí)現(xiàn)了。這樣 agent 就會(huì)獲得 id 為1的進(jìn)程

看完上述內(nèi)容,你們掌握node中cluster集群的作用是什么的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI