2011-12-19 63 views
10

我期待在Node.js v.0.6.0和更高版本中使Socket.io與native load balancing(「集羣」)工作多線程。Node.js,多線程和Socket.io

據我所知,Socket.io使用Redis來存儲其內部數據。我的理解是這樣的:我們不想爲每個工作人員產生一個新的Redis實例,而是要強制員工使用與Master相同的Redis實例。因此,連接數據將在所有員工中共享。

像這樣的事情在主人:

RedisInstance = new io.RedisStore; 

的,我們必須以某種方式通過RedisInstance工人並執行以下操作:使用舊,第三方集羣模塊

io.set('store', RedisInstance); 

靈感來自this implementation ,我有以下非工作實現:

var cluster = require('cluster'); 
var http = require('http'); 
var numCPUs = require('os').cpus().length; 

if (cluster.isMaster) { 
    // Fork workers. 
    for (var i = 0; i < numCPUs; i++) { 
    cluster.fork(); 
    } 

    var sio = require('socket.io') 
    , RedisStore = sio.RedisStore 
    , io = sio.listen(8080, options); 

    // Somehow pass this information to the workers 
    io.set('store', new RedisStore); 

} else { 
    // Do the work here 
    io.sockets.on('connection', function (socket) { 
    socket.on('chat', function (data) { 
     socket.broadcast.emit('chat', data); 
    }) 
    }); 
} 

想法?我可能會完全向錯誤的方向發展,任何人都可以指出一些想法?

+1

我不知道什麼接近你最終使用。 – 2013-06-03 19:04:37

回答

10

其實你的代碼應該是這樣的:

var cluster = require('cluster'); 
var http = require('http'); 
var numCPUs = require('os').cpus().length; 

if (cluster.isMaster) { 
    // Fork workers. 
    for (var i = 0; i < numCPUs; i++) { 
    cluster.fork(); 
    } 
} else { 
    var sio = require('socket.io') 
    , RedisStore = sio.RedisStore 
    , io = sio.listen(8080, options); 

    // Somehow pass this information to the workers 
    io.set('store', new RedisStore); 

    // Do the work here 
    io.sockets.on('connection', function (socket) { 
    socket.on('chat', function (data) { 
     socket.broadcast.emit('chat', data); 
    }) 
    }); 
} 

另一個選項是打開Socket.IO爲偵聽多個端口,並且有類似HAProxy的負載平衡的東西。 無論如何,你知道最重要的事情:使用RedisStore在一個進程外擴展!

資源:

http://nodejs.org/docs/latest/api/cluster.html
How can I scale socket.io?
How to reuse redis connection in socket.io?
Node: Scale socket.io/nowjs - scale across different instances
http://delicious.com/alessioaw/socket.io

+0

這個實現不會爲每個worker創建一個新的RedisStore嗎?另外,使用類似HAProxy的優點是什麼?似乎使用本地存在於Node中的功能更好。 – 2011-12-19 15:43:51

+2

HAProxy的優點:你可以在不同的端口上進行處理,你可以更仔細地監控並在死亡時重新啓動(使用monit,暴發戶)。還有,您需要爲每個工作人員創建一個新的RedisStore。認爲集羣是child_process.fork()之上的實現,所以你基本上覆制了N次應用程序(就我所知,這些進程共享相同的文件描述符)。 – alessioalex 2011-12-19 15:48:36

+0

我剛試過你的代碼示例,似乎沒有工作。單線程時,1500個連接運行高達50%的CPU(每個工作人員的工作量比樣本中多一點)。使用您的示例,在每個*進程運行高達80-90%的CPU之前,我無法獲得多達500個連接。很顯然,有些事情是錯誤的,因爲這會使情況惡化。 – 2011-12-19 16:08:13