如何在Twisted服务器中与Redis或Memcache建立持久连接
我正在学习和理解twisted是怎么工作的。为此,我创建了一个基本的回声服务器,这个服务器把用户输入的内容当作在redis服务器上存储的数据的“键”。如果用户输入的内容和数据库中的某个“键”匹配,它就会打印出对应的值;如果没有匹配的“键”,则会打印“找不到这个键”。
我在练习的时候避免使用@defer.inlineCallbacks
,想多练习一下如何使用Deferreds。以下是我的代码:
from twisted.internet import reactor, protocol
from txredis.client import RedisClient
REDIS_HOST = 'localhost'
REDIS_PORT = 6379
class Echo(protocol.Protocol):
def connectionMade(self):
self.factory.count += 1
self.transport.write('There are %d clients\n' % self.factory.count)
def dataReceived(self, data):
clientCreator = protocol.ClientCreator(reactor, RedisClient)
d = clientCreator.connectTCP(REDIS_HOST, REDIS_PORT)
def cb_redis_get(r, data):
d = r.get(data.strip())
def cb_result(x):
if x:
self.transport.write('%s\n' % x)
else:
self.transport.write('key not found\n')
d.addBoth(cb_result)
d.addCallback(cb_redis_get, data)
class EchoFactory(protocol.ServerFactory):
count = 0
protocol = Echo
def main():
reactor.listenTCP(1234, EchoFactory())
reactor.run()
if __name__ == "__main__":
main()
当一个客户端通过telnet 0 1234
连接并输入一个单词时,服务器会与redis服务器建立连接。这样一来,如果有100个客户端同时连接,代码就会创建100个与redis或memcache服务器的连接。
这可能是预期的行为,但我想知道是否可以利用twisted reactor,在服务器启动时创建一个持久连接,并将这个连接用于所有新的连接。这样的话,我就可以每个实例只使用一个连接,并重复利用它。
如果可以的话,有没有好的方法来实现这个功能,以及如何处理重新连接的问题?
1 个回答
看看这个 txredisapi 库。它是一个相当完整的 twisted 实现,支持单个连接和连接池(持久连接和非持久连接)用于 redis。
我已经在一个 twisted 项目中使用它几个月了,感觉非常不错。
等一下,可能我没理解你想问的是什么。
当我看你的代码时,发现了一些奇怪的地方,比如你似乎是在接收到 telnet 数据时就创建一个 redis 连接,这样的话,不仅仅是每个 telnet 创建一个连接,而是每次在 telnet 连接上有数据刷新时都会创建一个连接(这几乎肯定不是你想要的效果)。
看看这个 txredisapi 的示例,它们比我看到的 txredis 的示例要详细得多。
大致来说,你的逻辑应该分成两部分,一部分负责保持 redis 连接的活跃,另一部分(基本上就是你现在的代码)负责处理 telnet 连接并通过 redis 连接发送命令。txredisapi 库会为你处理所有的 redis 相关工作(...而 txRedis 可能也可以做到,我对那个库不太了解,但 txredisapi 的示例应该能帮助你)。
(这种类型的问题最近出现得很多,你可能会发现之前的一个回答对理解 twisted 中各部分的常见分离很有帮助,见: twisted 中的持久连接)