负载均衡:Node.js - Socket.io - Redis

时间:2013-06-10 17:09:38

标签: node.js express redis socket.io

我有3个运行NodeJ的服务器,它们与Redis(1个主服务器,2个从服务器)相互关联。

我遇到的问题是在单个服务器上运行系统工作正常,但是当我将其扩展到3个NodeJS服务器时,它会启动丢失的消息并且系统会变得不稳定。

我的负载均衡器不接受粘性会话。因此,每当客户端的请求到达时,他们都可以转到不同的服务器。

我将所有NodeJS服务器都指向Redis Master。

看起来socket.io正在每台服务器上存储信息,而不是使用redis进行分发。

我正在使用socket.io V9,我怀疑我没有任何握手代码,这可能是原因吗?

配置socket.io的代码是:

var express = require('express');
var io = require('socket.io');
var redis = require('socket.io/node_modules/redis');
var RedisStore = require('socket.io/lib/stores/redis');

var pub = redis.createClient("a port", "an ip");
var sub = redis.createClient("a port", "an ip");
var client = redis.createClient("a port", "an ip");
var events = require('./modules/eventHandler');

exports.createServer = function createServer() {
    var app = express();
    var server = app.listen(80);
    var socketIO = io.listen(server);

    socketIO.configure(function () {
        socketIO.set('store', new RedisStore({
            redisPub: pub,
            redisSub: sub,
            redisClient: client
        }));
        socketIO.set('resource', '/chat/socket.io');
        socketIO.set('log level', 0);
        socketIO.set('transports', [, 'htmlfile', 'xhr-polling', 'jsonp-polling']);
    });

    // attach event handlers
    events.attachHandlers(socketIO);

    // return server instance
    return server;
};

2 个答案:

答案 0 :(得分:2)

Redis仅从主设备同步到从设备。它永远不会从奴隶同步到主人。因此,如果您正在写入所有3台计算机,那么将在所有三台服务器上同步的唯一消息将是击中主服务器的消息。这就是为什么你看起来像是在丢失消息。

更多信息here

  

只读奴隶

     

由于Redis 2.6从站支持只读模式   默认情况下启用。此行为由   redis.conf文件中的slave-read-only选项,可以启用和   使用CONFIG SET在运行时禁用。

     

只读奴隶将拒绝所有   写命令,因此无法写入从站   因为一个错误。这并不意味着构思了该特征   将一个从属实例暴露给互联网或更普遍地暴露给一个   存在不受信任的客户端的网络,因为管理命令   像DEBUG或CONFIG仍然启用。但是只读的安全性   实例可以改进使用redis.conf中的命令禁用命令   rename-command指令。

     

您可能想知道为什么可以还原   默认并具有可以成为写入目标的从属实例   操作。 原因是,如果此写入将被丢弃   从站和主站将重新同步,或者如果是从站   重新启动,通常有短暂的数据,这是不重要的,可以   被存储到奴隶。例如,客户可能会获取有关的信息   从属实例中主服务器的可达性,以协调故障转移   策略。

答案 1 :(得分:0)

我到了这个帖子:

在nodejs服务器和负载均衡器之间建立“代理”可能是个好主意。 通过这种方法,XHR-Polling可以在没有Sticky会话的负载均衡器中使用。

Load balancing with node.js using http-proxy

使用nodejs-http-proxy我可以有自定义路由路由,例如。通过在socket.io的“connect url”上添加一个参数。

之前有人试过这个解决方案吗?