微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Redis PubSub 未重新连接

如何解决Redis PubSub 未重新连接

我目前正在围绕 Redis Pubsub 开发包装器以获取 Subscriber 实例。我正在尝试使其对连接中断具有健壮性。 根据文档,“在发生网络错误或超时等断开连接的情况下,PubSub 对象将在重新连接时重新订阅所有先前的通道和模式”。但它似乎对我不起作用。

这是一个 PubSub 流程的工作示例:

>>> import redis
>>> r = redis.Redis(host="172.17.0.2",port=6379)
>>> r.ping()
True
>>> sub = r.pubsub()
>>> sub.subscribe("test")
>>> r.publish("test","test")
1
>>> sub.get_message()
{'type': 'subscribe','pattern': None,'channel': b'test','data': 1}
>>> sub.get_message()
{'type': 'message','data': b'test'}

此时,我关闭了我的 Redis 实例。 r.ping() 按预期产生 redis.exceptions.ConnectionError

此时,我重新启动了我的 Redis 实例。

>>> r.ping()
True
>>> r.publish("test","test")
0
>>> sub.get_message()
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
  File "/home/robin/.conda/envs/rb-linkvision/lib/python3.6/site-packages/redis/client.py",line 3617,in get_message
    response = self.parse_response(block=False,timeout=timeout)
  File "/home/robin/.conda/envs/rb-linkvision/lib/python3.6/site-packages/redis/client.py",line 3503,in parse_response
    if not block and not conn.can_read(timeout=timeout):
  File "/home/robin/.conda/envs/rb-linkvision/lib/python3.6/site-packages/redis/connection.py",line 734,in can_read
    return self._parser.can_read(timeout)
  File "/home/robin/.conda/envs/rb-linkvision/lib/python3.6/site-packages/redis/connection.py",line 321,in can_read
    return self._buffer and self._buffer.can_read(timeout)
  File "/home/robin/.conda/envs/rb-linkvision/lib/python3.6/site-packages/redis/connection.py",line 231,in can_read
    raise_on_timeout=False)
  File "/home/robin/.conda/envs/rb-linkvision/lib/python3.6/site-packages/redis/connection.py",line 201,in _read_from_socket
    raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR)
redis.exceptions.ConnectionError: Connection closed by server.

Redis 连接似乎已正确重新启用,但 PubSub 实例不再工作。我目前正在使用一种解决方法

>>> sub.reset()
>>> sub.subscribe("test")
>>> sub.get_message()
{'type': 'subscribe','data': 1}

我对我的解决方法很满意,但文档明确指出这应该自动处理。有什么我没有正确做的吗? 感谢您的回答!

解决方法

使用 health_check_interval 选项创建 redis 客户端可以解决问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。