最近在开发一个游戏的客服系统,同一时间咨询问题的玩家多,为了保证服务器高可用,需要利用分布式,另外服务器宕机还需要玩家无感知重连,最关键的一点是如何实现服务器的高扩展性,即性能不足时,如何以最少的代价增加一台新的服务器。
1.单台websocket
单台消息互传实现十分简单,通过websocket中转就可以了,不再多加赘述。
2.多台websocket
当客户端不在同一台服务器上时,如何实现消息互通?
一开始的时候,我是想着把server A 与 server B 通过websocket连接起来,互发消息,这种方案在服务器数量小的时候,维护起来也不算麻烦。
例如增加server C 就要把 A、B、C连起来,但是每增加一台服务器,工作量指数级增长,还要考虑到服务器宕机、服务器心跳的各种问题,想想都头疼。
3.多台websocket消息推送
这下舒服了。
1.使用全局redis存储客户端与服务端的关系;
2.webscoket服务器各自订阅不同的消息队列。
发消息流程:
情况一:
clientA 给 clientB 发消息时,先从缓存中读取clientB在哪个服务器上,发现clientA 与clientB 在同一服务器时,消息直接发送至clientB
情况二:
clientB 给 clientC 发消息时,从缓存中读到clientC和clientB并不在同一服务器上,例如clientC在wsB,那么clientB将消息发送到rabbitmq队列B,然后rabbitmq推送到wsB,wsB给clientC发送消息。
4.总结
- 新增服务器只需要多订阅一条消息队列。
- 服务器宕机时,客服端重连websocket,重新绑定redis的server关系。
- rabbitmq的ack机制保证消息的可靠性。
5.改进
压缩消息,节省带宽。推荐使用google的protobuf,就是稳。