最近再调整游戏服务器的架构,有了些感悟,趁着热乎先记录下来。

目前架构

首先祭出一张目前的简单架构图:

基本流程是:
1. 用户先连接CDN,获取可用服务器列表
2. 基于算法随机到其中一台游戏服务器(长连接)
3. 游戏服务器内部交互都通过Redis的订阅模式完成。
4. 保留一个Hub服务器,处理全局任务(排行榜之类)

分析下这个结构的好处:
1. 扩展简单,对于游戏压力来说,只要CDN不跨掉就可以了。
2. 跨服经过redis,这个东西比较成熟,使用起来也很简单
3. 业务划分简单,玩家部分走GS, 系统部分走Hub.

当然也有一定的问题:
1. Hub有可能提前成为瓶颈
2. Redis本身无法保存消息

优化版本

这里我准备用一个专门的socket服务器来替代redis,不关注任何业务,只是做简单的转发。这就是前面提到的调节服务器(Intermediary)。它会支持两种转发策略:
1. 点到点:业务对状态敏感,直接转发。
2. 随机点:业务对状态并不敏感,随机转发。

这里虚线框中的服务器可以按照业务组成一个族群,那么这个族群的首领就是调节服务器。它扮演的角色就是:
1. 统一收发对外消息
2. 内部协调消息扭转
3. 消息状态的维护

由于Hub变成了无状态的,所以它同样和GS一样十分方便的可以扩展。

扩展版本

其实我们可以把整个服务器架构都按照这种族群的思路来设计。其中调节服务器就类似于“网关”。他们是进出整个族群的出入口。那么我们可以看到一个最简单的服务器就是一个族群。当我们需要它按照业务无限扩容时候,就变成如下的一个拓扑结构:

这里的业务也是多种定义:可以是普通的游戏逻辑族群,也可以是专门的战斗族群,或者是任务族群,甚至是存储族群都可以的。

可以看到这套架构是比较松耦合的,大家都是靠通信协议在协调服务器通信。新的业务加入和去除也比较方便。

可能这里对于协调服务器的单点情况是有点担心的。我这里考虑到的做法:
1. 利用虚地址或者一致性hash之类保证它的高可用(横向)
2. 提升本身机器的性能(纵向)
3. 根据业务动态的裂变或者合并这个节点

前面两点比较容易理解。第三点的意思是,比如我很多业务都走Hub服务器族群,让它的协调服务器变得压力很大,这时我们可以考虑拆分这些业务:比如把排行榜和定时任务拆开。这样就变成了两个族群。同理,反向操作也是可以的。

关系图如下:

总结

可以看到整个架构的一个进化过程其实是很自然也很动态的。但需要配合很多CI/CD的工具来达到这个目的。不过后面我会先用netmq来实现这个框架。

参考

https://netmq.readthedocs.io/en/latest/