我有一个针对websocket的Tornado服务器。我在那里定义了一个用于存储连接用户的全局字典。
...
# Global dictionary
client_dict = {}
class MessagesHandler(tornado.websocket.WebSocketHandler):
...
def open(self, v):
...
# Put {user_id: self} that it will able to send message somebody
# And make sure that there are no copy of self
if self.user_id in client_dict:
is_self_not_there = True
for i in client_dict[self.user_id].values():
if i is self:
is_self_not_there = False
if is_self_not_there:
client_dict[self.user_id].update({max(client_dict[self.user_id], key=int)+1:self})
else:
client_dict.update({self.user_id : {0:self}})
@tornado.gen.coroutine
def on_message(self, mess):
...
# send mesage to certain user
for k, recipient_wsconnection in client_dict[recipient_id].items():
recipient_wsconnection.write_message('Ko ko ko')
...
...
当我只启动一个过程时,它工作正常。
但我想在生产中使用supervisord,在不同的端口上启动多个实例。并通过nginx将这些实例代理到Internet。我决定这样做只是为了实现负载平衡。
如您所见,有几个实例,每个实例都有一个自己的独立字典(client_dict)。
我有一个想法(通过pickle)序列化每个用户(MessagesHandler的一个实例)并将其存储在Redis中。但是当我反序列化它时,它就变成了现有对象的副本。
有没有办法共享内存并在那里存储全局字典?
或许我的Tornado服务器还有另一种负载均衡方式吗?
也许Consistent hashing可以帮助我,但我不太明白如何实现它......