有没有人知道一个好的解决方案,把一个基于node.js - socket.io的应用程序扩展到多个核上?我目前正在测试socket.io文档中提出的解决方案,以便在多个节点上使用socket.io,但没有取得具体的成功。
我已经在github:https://github.com/liviuignat/socket.io-clusters上创建了一个操场,它是来自socket.io站点的聊天应用程序的修改拷贝。它使用express,cluster,socket.io@1.1.0和socket.io-redis。
目前,在分支sticky-session中也有一个使用feature/sticky的实现,它似乎工作得更好。
最后,需要将应用程序发布到Heroku,在多个dynos上进行缩放。
最初,我尝试这样做--只为集群节点启动服务器,但我总是得到错误: failed:连接在收到握手响应之前已关闭。
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 {
var server = new Server({
dirName: __dirname,
enableSocket: true
})
.setupApp()
.setupRoutes()
.start();
}然后,我还尝试为主节点启动服务器:
if (cluster.isMaster) {
var server = new Server({
dirName: __dirname,
enableSocket: true
})
.setupApp()
.setupRoutes()
.start();
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
} else {
var server = new Server({
dirName: __dirname,
enableSocket: true
})
.setupApp()
.setupRoutes()
.start();
}我还使用了sticky-session和socket.io-redis在分支feature/sticky中进行了尝试,这似乎成功地执行了,但仍然不是一个好的解决方案:
if (cluster.isMaster) {
sticky(function() {
var server = new Server({
dirName: __dirname,
enableSocket: true
})
.setupApp()
.setupRoutes();
return server.http;
}).listen(3000, function() {
console.log('server started on 3000 port');
});
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
} else {
sticky(function() {
var server = new Server({
dirName: __dirname,
enableSocket: true
})
.setupApp()
.setupRoutes();
return server.http;
}).listen(3000, function() {
console.log('server started on 3000 port');
});
}接下来的几天,我会做更多的测试,但是,如果有人能想出一些想法的话,这会有很大的帮助。
谢谢,
发布于 2014-09-30 14:42:37
你可能在找socket.io-redis。http://socket.io/blog/introducing-socket-io-1-0/ (滚动到“可伸缩性”)
下面是一个关于如何使用socket.io +express创建脚手架的简短示例:
var cluster = require('cluster');
var express = require('express')
, app = express()
, server = require('http').createServer(app);
var
io = require('socket.io').listen(server)
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
var workers = process.env.WORKERS || require('os').cpus().length;
/**
* Start cluster.
*/
if (cluster.isMaster) {
/**
* Fork process.
*/
console.log('start cluster with %s workers', workers-1);
workers--;
for (var i = 0; i < workers; ++i) {
var worker = cluster.fork();
console.log('worker %s started.', worker.process.pid);
}
/**
* Restart process.
*/
cluster.on('death', function(worker) {
console.log('worker %s died. restart...', worker.process.pid);
cluster.fork();
});
} else {
server.listen(process.env.PORT || 9010);
}Redis有发布/订阅,所有socket.io节点都需要订阅redis才能从一个通道获取所有消息。这样,一个进程就可以将消息广播到信道(发布),而所有其他进程都以最小的延迟接收消息,以便将消息广播到其连接的客户端(订阅)。您甚至可以通过基于redis的会话来扩展这一点。
在我看来,您所指的集群模块有点误导。就我所理解的概念而言,它有助于创建非虚拟子进程,但不会“同步”多个节点之间的通道。如果你的客户不需要和别人沟通,那也没关系。如果要向所有节点上的所有连接客户端广播消息,则需要redis模块。
https://stackoverflow.com/questions/26123355
复制相似问题