我有一台使用Redis和Socket.IO的服务器。如果用户连接到socket.IO,服务器将运行greenlet并订阅redis通道。如果用户断开连接,greenlet将取消订阅该频道。
经过大量连接和断开后,我在redis-cli中使用'client list'命令,我发现取消订阅的数量是加性的,它永远不会像其他命令那样关闭。它最终会导致“太多文件打开错误”
我的代码是
class ListenMsgThreading(Greenlet):
def __init__(self, app_eui, request_sid):
Greenlet.__init__(self)
self.ps = redis_db.pubsub()
self.ps.subscribe('channel')
def stop(self):
self.ps.unsubscribe('channel')
def run(self):
for item in self.ps.listen():
if item is not None:
print(item)
我注意到原因可能是
超时仅适用于数字客户端,并且它不适用于发布/订阅客户端,因为发布/订阅连接是推式连接,因此空闲的客户端是常态。
我应该为unsubscribe命令实现超时吗?或者使用其他方法来停止订阅?
答案 0 :(得分:1)
查看代码
https://github.com/andymccurdy/redis-py/blob/master/redis/client.py#L2281
我可以猜到这个问题。看起来PubSub对象检查subscribe
命令上的连接池中的连接,但不会在unsubscribe
上释放它。它应该在你的greenlet超出范围(del
方法)时释放它 - 你是否因为某种原因将它们放在范围内以便它们不会被释放?这会导致内存问题......
但是,您可以尝试使用reset
方法强制释放该连接,而不会影响范围问题。
self.ps.unsubscribe()
self.ps.reset()