4

我有 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;
};
4

2 回答 2

2

Redis 仅从主服务器同步到从服务器。它从不从从属同步到主控。因此,如果您要写入所有 3 台机器,那么最终会在所有 3 台服务器之间同步的唯一消息将是命中主服务器的消息。这就是为什么看起来您缺少消息的原因。

更多信息在这里

只读从机

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

只读从机将拒绝所有的写命令,因此不可能因为错误而写入从机。这并不意味着该功能旨在将从属实例暴露给互联网或更一般地暴露给存在不受信任的客户端的网络,因为仍然启用了诸如 DEBUG 或 CONFIG 之类的管理命令。然而,只读实例的安全性可以通过使用 rename-command 指令禁用 redis.conf 中的命令来提高。

您可能想知道为什么可以恢复默认值并拥有可以成为写入操作目标的从属实例。原因是,如果从服务器和主服务器重新同步,或者从服务器重新启动,这些写入将被丢弃,但通常会有一些不重要的临时数据可以存储到从服务器中。例如,客户端可能会获取有关从属实例中主控的可达性的信息来协调故障转移策略。

于 2013-06-10T20:09:49.770 回答
0

我来到这个职位:

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

使用 http-proxy 与 node.js 进行负载平衡

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

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

于 2013-06-11T14:17:46.920 回答