Liv*_*nat 6 heroku scale redis node.js socket.io
有没有人知道一个很好的解决方案来扩展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.
最初我尝试做这样的事情 - 只为群集节点启动服务器,但我总是收到错误:失败:连接在收到握手响应之前关闭
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();
}
Run Code Online (Sandbox Code Playgroud)
然后我尝试为主节点启动服务器:
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();
}
Run Code Online (Sandbox Code Playgroud)
我也尝试使用它们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');
});
}
Run Code Online (Sandbox Code Playgroud)
我将在接下来的几天里做更多的测试,但是,如果有人想出一些想法,那将会有很大的帮助.
谢谢,
您可能正在寻找 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);
}
Run Code Online (Sandbox Code Playgroud)
Redis具有pub/sub功能,所有socket.io节点都需要订阅redis才能从通道获取所有消息。这样,一个进程可以将消息广播到通道(发布),而所有其他进程以最小的延迟接收消息,并将其广播到其连接的客户端(订阅)。您甚至可以使用基于 redis 的会话来扩展它。
我认为您所指的集群模块有点误导。据我理解这个概念,它有助于创建单独的子流程,但不会跨多个节点“同步”通道。如果您的客户不需要与其他人沟通那就没问题。如果您想向所有节点上所有连接的客户端广播消息,则需要 redis 模块。
| 归档时间: |
|
| 查看次数: |
1412 次 |
| 最近记录: |