美文网首页Go语言游戏服务器相关Golang语言社区
【转】游戏服务器集群设计思路

【转】游戏服务器集群设计思路

作者: Golang语言社区 | 来源:发表于2018-12-10 17:52 被阅读16次

    对于我们的游戏服务器端来说,除了要满足一般的MMO服务器端功能要求外,还要达到两个附加需求:
    1、高可用性
    避免任何服务的单点故障,各种关键服务都提供一定的冗余和故障自动切换机制。
    2、动态负载均衡
    游戏世界和游戏场景服务能够根据服务器网络中机器的负载情况,选择合适的宿主机器创建和动态迁移。
    提供场景动态分区的技术,支持单个场景中支持巨量玩家在线。
    因此,我们需要设计一个支持不同层面高可用性和负载均衡的游戏服务器集群系统。
    下面谈谈我的设计思路。
    不妨先从服务器运营、部署和管理的角度出发来来考虑。对于规模较大的MMO来说,服务器通常会部署在多个数据中心里。每个数据中心会集中部署大量服务器,这些服务器通常被作为一个整体来集中管理,诸如玩家看到的“网通1区”、“电信2区”这样的称呼。我把这样的一组服务器称为一个游戏域。本文主要叙述一个游戏域内的服务层次设计。
    一个游戏域内主要的组件以如下方式组织:
    游戏域
    登录服务:提供登录验证服务,在后期可能会加入登录排队服务。
    前端服务:相当于客户端和服务器端间的防火墙,提供包的验证、过滤、汇聚和分发功能。
    数据服务:提供游戏全局数据存取,如帐号信息等,通常底层由成熟的数据库支持。
    消息服务:主要指聊天、系统广播等即时消息服务,也可以提供类似信箱等非即时消息。
    游戏世界
    游戏场景:包括集市、PvP副本、PvE副本等场景。
    场景分区:主要用于支持同一场景中容纳巨量玩家,可以根据区域进行几何划分(参见场景集群的划分 ),也可以根据玩家关联程度等其他特性划分。
    为简化设计,考虑到应用特点,我们的系统设计为集中-分布式,而非完全分布式。
    对于一个游戏域来说,最顶层由域管理器(Domain Manager,DM)作为管理中心。这里的域管理器有些类似于简化的Windows域控制器(Domain Controller),主要有两方面作用:1)负责其之间下层组件的创建与负载均衡策略,如游戏世界的创建;2)作为一个服务注册中心,起到类似于全局 DNS的作用。
    在高可用性方面,我们系统中的各种组件基本都采用主节点-复制节点(Master-Repo)结构。对于游戏域而言,正常情况下,任何时刻一个游戏域中有一个唯一的负责决策的域管理器,即主域管理器(Master Domain Manager,MDM)。为满足高可用性要求,一个主域管理器会有多份拷贝,我们称之为复制域管理器(Repo Domain Manager, RDM)。注意,为简化起见,我们不提供域管理器本身的负载均衡支持,但支持域管理器的故障切换。当MDM出现故障时,系统会选择一个RDM升级为 MDM,并根据需要再启动一个RDM,以满足DM副本数量的要求。一个DM启动的时候,会发通过组播查询域中的DM,如果此时发现MDM,在MDM同意的情况下,就作为RDM与之通过数据复制进行同步;反之,如果没发现MDM,就和其他RDM协商,确定自身能否成为MDM。进一步设计和实现高可用性时,需要考虑集群脑裂的问题(split-brain,不熟悉的同学请google 之)。
    MDM还会根据管理数据服务、消息服务、前端服务和游戏世界等组件高可用性与负责均衡。
    客户端登录时,根据本地存储的服务器地址列表与登录服务器进行连接。因此,登录服务的负载均衡,可以结合DNS负载均衡或类似F5的负载均衡设备来实现。客户端一旦通过登录验证,就会由MDM选择合适的游戏前端服务器与之进行连接。
    为提供高可用性,前端服务(Front-end Service, FS)也采用主节点-复制节点的设计,客户端会缓存主前端服务地址(Master Front-end Service, MFS)和复制前端服务(Repo Front-end Service, RFS)地址。前端服务还用来存取独立于特定游戏世界的信息,如玩家的角色信息。
    和其他需要高可用性的服务类似,游戏世界、游戏场景和场景分区都采用Master-Repo体系结构。
    每个游戏世界有一个相应的主游戏世界服务器(Master World Server, MWS),其作用有两方面:1)管理游戏世界的全局信息;2)管理游戏场景的负载均衡和故障切换。
    每个游戏场景有一个相应的主场景服务器(Master Scene Server, MSS),其主要作用也有两方面:1)管理特定场景的全局信息;2)管理场景分区的负载均衡和故障切换。一个游戏场景可以由一个或多个场景分区组成。
    每个场景分区有一个相应的主场景分区服务(Master Scene Partion Server, MSPS),负责其中游戏实体对象的管理。通常,前端服务器将会把大多数客户端请求直接转发到玩家角色所属的场景分区中。
    对于任何一个分布式系统来说,主要有两方面功能:其一,向上提供分布式服务接口;其二,向下提供对底层分布资源的管理。以上主要介绍了游戏集群的服务接口层次。此外,如前所述,在资源管理方面,我们采用Master-Repo结构,将高可用性和负载均衡调度的功能融入到了游戏逻辑服务器中。这种设计把两种看似正交的功能耦合在了一起,增加了系统复杂性。其实,正是通过结合游戏逻辑和集群要求的特点,我们减少了额外层次,简化了系统设计和多余消息传递的开销。而且,通过采用相似的Master-Repo结构,似的集群资源调度本身也是可以在不同组件间复用的。
    在集群资源管理方面,还有一个重要的方面没有提到,那就是对物理机器资源的管理。为做到这一点,我们在每个物理节点(服务器的操作系统)中运行着一个后台服务,我们称之为节点代理(Node Agent,NA),起主要作用有两方面:1)负责监测系统CPU、内存和网络资源的情况,并提供查询接口;2)负责启动和停止其他的游戏服务进程,如前端服务器、游戏世界服务和场景服务等。在项目的后期,还可以通过NA加入一些方便系统管理的功能,如服务器端软件统一升级等。
    通过以上叙述,我们简要的介绍了支持负载均衡和高可用性的MMO服务器集群的构件和设计思路。因时间关系,还有一些构件和机制没有再这里讨论,如系统管理服务器设计,不同游戏域之间的通信等。随着项目的进展,设计思路的进一步成熟,这些话题会在后续的文章中讨论。


    Golang语言社区

    相关文章

      网友评论

        本文标题:【转】游戏服务器集群设计思路

        本文链接:https://www.haomeiwen.com/subject/zhedhqtx.html