[Node.js] Cluster,把多核用起來

來源:互聯網
上載者:User

標籤:des   style   blog   http   color   io   os   使用   ar   

引子

眾所周知,雖然Node的底層有一個IO線程池,但其應用程式層預設是單線程啟動並執行,對於多核CPU環境來說,是一種資源的浪費。

所幸Node提供了child_process 模組,讓開發人員得以開多個進程,實現每個進程各自利用一個CPU,以實現多核的利用。

child_process 模組給予Node 可以隨意建立子進程的能力。因為 child_process 類本身是一個 EventEmitter,所以處理序間通訊很容易;且父子處理序間通訊並不通過網路層,而是在核心中完成,高效。

但 child_process 對於開發人員來說,編程模型還是過於複雜,需要操心的細節過多,比如:父進程崩潰了,子進程回收是需要開發人員提供代碼來處理的——如果開發人員只是想單純利用多核模型,對具體背景工作處理序的控制粒度並沒有太多設想,那這種開發模型無疑是令人頭疼的。

針對這個問題,Node 提供了 Cluster 模組。Cluster 簡化了父子模型編程模型,只區分:當前進程是不是 Master,是 Master 就可以fork子進程,不是那就請行使Worker 職責。至於什麼資源的回收,負載的調配,uncaughtException的處理,它自有安排。

本質上, Cluster 是 child_process 和 net 模組的組合應用。它不僅簡化了編程模型,還使得共用監聽同一連接埠成為可能。

更多關於Cluster的原理這裡不表,感興趣可以移步 → 解讀Nodejs多核處理模組cluster

情境

用Node快速搭站呢,當然就用 express 咯  所以,需求就是用 Cluster 做個單機叢集,多進程跑 express,提升網站的輸送量。

實驗

先用 express-generator 搭個框子,模板引擎還是使 ejs 吧:

express -e myapp2

express-generator 預設會把 app.js 產生好,一行代碼不寫,一個完備的 http server 是已經實現的了。So,我們可以實現一個 Cluster 單機叢集,clusterMaster.js:

//CPU幾核?var cpus = require(‘os‘).cpus().length; //子進程監聽訊息處理函數var workerListener = function (msg) {    if (msg.access)        console.log(‘user access %s, worker [%d]‘,                            msg.access, msg.workerid);};//fork新的子進程函數var forkWorker = function(listener){    var worker = cluster.fork();    console.log(‘worker [%d] has been created‘,                                  worker.process.pid);    worker.on(‘message‘, listener);    return worker;}; //Cluster處理var cluster = require(‘cluster‘);if (cluster.isMaster) {    for (var i = 0; i < cpus; i++) {        forkWorker(workerListener);    }} else {    var app = require(‘./app‘);    return app.listen(3000);} //Cluster收到子進程退出訊息cluster.on(‘exit‘, function (worker, code, signal) {    console.log(‘worker [%d] died %s, fork a new one.‘,        worker.process.pid, code || signal);    forkWorker(workerListener);});//Cluster收到子進程運行訊息cluster.on(‘online‘, function(worker){    console.log(‘worker [%d] is running.‘, worker.process.pid);});

可以看到:

  • Cluster 是通過 isMaster 來區分父子進程的。父進程中處理建立邏輯:根據 CPU的核心數,建立相應數量的子進程;子進程中運行具體的 Server 建立代碼。夠簡單的模型~
  • 在 Cluster 父進程端,是始終能獲知 當前worker 的。而當前 worker 的 pid 呢,在有worker 控制代碼情況下,對應的是 woker.process.pid;在子進程啟動並執行上下文中,就是 process.pid。這不難理解~
  • 我們為新fork出來的子進程添加了訊息處理函數,使得任何子進程運行代碼,都可以隨時利用訊息觸發它:用途挺廣泛的,稍後會示範一個例子
  • 在子進程退出時,Cluster 父進程會收到 exit 訊息,這時會重fork一個新子進程來補缺

假設使用者訪問這個網站: localhost:3000/,我希望告訴他,是哪個子進程在為他渲染頁面。那麼,在 /routes/ 添加一個express 路由 index.js:

var express = require(‘express‘);var router = express.Router(); /* GET home page. */router.get(‘/‘, function (req, res) {    res.render(‘index‘, { title: ‘Express‘,                               workerid: process.pid });    process.send({access: ‘/‘, workerid: process.pid});}); module.exports = router;

可以看到,除了路由,還使用 process.send 發送了訊息,它實際上會觸發之前代碼中子進程註冊的 workerListener,向它彙報路徑和進程號;由於使用了 render,那自然是少不了 ejs 模板, /views/index.js:

<!DOCTYPE html><html>  <head>    <title><%= title %></title>    <link rel=‘stylesheet‘ href=‘/stylesheets/style.css‘ />  </head>  <body>    <h1><%= title %></h1>    <p>Welcome to <%= title %></p>    <p>[<%= workerid %>] worker is serving for you.</p>  </body></html>

模板會將 render 攜帶的子進程 pid 渲染到頁面上; 當然少不了在 app.js 中添加路由映射:

var routes = require(‘./routes/index‘); app.use(‘/‘, routes);

運行程式,在 shell 下 看看進程產生情況:

一父四子,試著用 kill 64163殺死一個子進程。可以在console看到,主進程收到了 exit訊息,並重新fork一個新的進程:

測試一下負載,用 Chrome 重複訪問幾次網站,似乎 worker 子進程 一直未變:

用 ab 來類比一下並發,讓它一個核忙不過來:


換 Safari 瀏覽器訪問一下網站,這次換了一個 worker 進程來服務,速度還不慢 

 

 

 

更多文章請移步我的blog新地址: http://www.moye.me/ 

[Node.js] Cluster,把多核用起來

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.