2

我希望其他人以前遇到过这个问题:

问题描述

我已将 Socket.IO 配置为使用 redis-store 模块,该模块非常适合在向房间广播/发出事件时保持我们的节点实例同步。但是,我一直在测试故障点,似乎当 redis 实例重新启动时,节点服务器停止接收来自其他节点的消息。

这是我设置socket.io客户端的方式(在这段代码之前创建redis连接)

// Setup the socket server for web clients
self.ioServer = socketIo.listen(9000);
self.ioServer.enable('browser client minification');    // send minified client
self.ioServer.set('log level', 3);

self.ioServer.set( 'store', new socketIo.RedisStore ({
        redisPub: self.redisPub, 
        redisSub: self.redisSub, 
        redisClient: self.redisStore
    })
);

本质上,每当 redis 崩溃/重启时,socket.io redis-store 无法继续通过 redis 向其他节点服务器发送事件。

重新连接到 redis 服务器是否需要采取任何特殊步骤?我花了很多时间四处寻找,希望能找到解决这个问题的方法,但没有任何运气。

问候,

-瑞安

4

2 回答 2

3

万一有人对此感兴趣,这是我为上述问题实施的修复:

由于系统正在为 socket.io 节点使用集群,因此我正在捕获 redis 连接(reidsPub、redisSub 等)上的任何“结束”事件并终止分叉进程。在主进程上,我捕捉到子进程的退出并重新分叉。

附带说明一下,我还发现了 redis 和 socket.io 的 redis-store 的另一个烦人的问题:如果没有与 redis 交换数据,redis 连接最终将超时。为了解决这个问题,我必须实现一个简单的保持活动功能,该功能每 15 秒运行一次,它与 redis 交换所有上述 redis 连接的数据。

通常我可以使用默认的redis客户端重新连接逻辑,但是因为我无法知道redis服务器是否真的重新启动,或者它是否只是超时。

于 2012-07-16T02:01:09.153 回答
1

我没有详细介绍 redis-store 的实现。我不相信带有 redis 的 pub-sub 默认备份到磁盘,如果服务器重新启动,消息就会丢失。除非 redis-store 已经为您做同样的事情,否则除了使用 pub-sub 之外,您还可以使用列表或排序集来存储消息。

如果 redis-store 默认不提供,您将需要确保您的列表/排序集不会增长太大而对性能产生负面影响。您可以考虑使用 MULTI/EXEC(并查看 ACK 消息)事务进行 ACID 保护,并确保消息不会被删除,除非您的订阅者处理/使用。

您可以随时查看提供持久(磁盘支持)消息队列/主题的其他消息服务器,例如 ActiveMQ 等。

希望能帮助到你。

于 2012-07-09T03:17:44.850 回答