Node-redis: 重新连接后订阅不接收数据

创建于 2017-07-05  ·  6评论  ·  资料来源: NodeRedis/node-redis

node_redis :2.7.1
Redis的:3.2
平台:Amazon Linux
描述:
当redis的快照发生时,它将断开redis客户端的连接。 客户端重新连接并重新订阅,但是,它们不再接收数据。 这可以通过在redis-cli上发出SAVE命令来重现。

JS

const redis = require('redis');
const redisClient = redis.createClient({
  host: config.redisEndpoint,
  port: config.redisPort,
});

redisClient.on('connect', () => {
  console.log('Connected to Redis');
  console.log('subscription_set:', redisClient.subscription_set);
});

redisClient.on('reconnecting', (stats) => {
  console.log('Reconnecting to Redis', stats);
});

redisClient.on('error', (error) => {
  console.log('Failed to connect to Redis: ', error);
});

redisClient.on('subscribe', (channel, count) => { // eslint-disable-line no-unused-vars
  console.log('Subscribed to: ', channel, count);
});

redisClient.on('message', (channel, message) => { // eslint-disable-line no-unused-vars
  console.log('Received from: ', channel, message);
});

redisClient.subscribe('test');

日志

初始连接

info: Connected to Redis
info: subscription_set:
info: Subscribed to:  test 1

在redis-cli中发出SAVE命令

info: Error: Redis connection to 34.213.3.19:6379 failed - read ECONNRESET
info: Reconnecting to Redis delay=983, attempt=4, code=ECONNRESET, errno=ECONNRESET, syscall=connect, address=127.0.0.1, port=6379, total_retry_time=1118, times_connected=1
info: Connected to Redis
info: subscription_set: subscribe_test=test
info: Subscribed to:  test 1

此时,客户端将不再接收发布到通道测试的任何数据。 如果您有任何疑问或需要更多信息来复制,请告诉我。

最有用的评论

好了,终于可以可靠地复制了。 有一些要求:

  • Redis 3.2.0-必须设置tcp-keepalive 0
  • 设置频道
  • 配置节点脚本进行连接并订阅频道
  • 等待2小时1分钟

您会看到,每2小时(至少对我来说)是ECONNRESET错误。 此时,套接字似乎仍在Redis中处于打开状态,但也许节点进程已丢失对它的引用并打开了一个新的套接字? 一夜之间,从redis-cli发出CLIENT LIST ,我希望每2小时连接1个客户端,加上当前正在运行的进程。

请务必注意,所有客户端都已成功重新连接,但未接收到数据。 我有一种预感,即数据已被推出,但是对于旧的连接却不是新的连接……但这完全是一种预感。

现在,我不是100%确定这是一个node_redis错误还是实际上是一个节点错误,因此,如果这是错误的提交位置,请告诉我。 我很乐于尝试调试/逐步调试,但是时间有限。

修复方法是设置tcp-keepalive 300 ,以保持连接处于活动状态...但这有点奇怪,因为客户端应该能够成功地重新连接。

所有6条评论

@BridgeAR @iamjem可能与#1249相关

感谢您的详细说明,但是我还无法复制它。 当我通过redis-cli发出SAVE ,连接不会重置。

当我手动停止redis服务器并重新启动它时,似乎可以正常接收消息。

我已经在Mac上进行了测试,也会尝试在Linux上重现它

嗯...这很有趣。 它是通过从源构建完全的redis安装而发生的。 我更改的唯一选项是允许远程连接。 我会尽快查看一下,看看是否能解决问题。 @jdegger

@jdegger我无法在本地进行复制,仅在超级特定条件下才能在AWS中进行复制。 我可以创建此AMI的第二个副本,并提供允许您重现的代码,但这似乎是在AWS中运行的特定功能。 让我知道您是否有兴趣...否则我会说继续并解决问题

好了,终于可以可靠地复制了。 有一些要求:

  • Redis 3.2.0-必须设置tcp-keepalive 0
  • 设置频道
  • 配置节点脚本进行连接并订阅频道
  • 等待2小时1分钟

您会看到,每2小时(至少对我来说)是ECONNRESET错误。 此时,套接字似乎仍在Redis中处于打开状态,但也许节点进程已丢失对它的引用并打开了一个新的套接字? 一夜之间,从redis-cli发出CLIENT LIST ,我希望每2小时连接1个客户端,加上当前正在运行的进程。

请务必注意,所有客户端都已成功重新连接,但未接收到数据。 我有一种预感,即数据已被推出,但是对于旧的连接却不是新的连接……但这完全是一种预感。

现在,我不是100%确定这是一个node_redis错误还是实际上是一个节点错误,因此,如果这是错误的提交位置,请告诉我。 我很乐于尝试调试/逐步调试,但是时间有限。

修复方法是设置tcp-keepalive 300 ,以保持连接处于活动状态...但这有点奇怪,因为客户端应该能够成功地重新连接。

@shmendo

我们的结果还表明,ECONNRESET错误每2小时发生一次。 但是我检查了tcp-keepalive,它是300

CONFIG GET tcp-keepalive
1) "tcp-keepalive"
2) "300"
此页面是否有帮助?
0 / 5 - 0 等级