亚马逊AWS官方博客
Amazon GameTech 架构最佳实践系列 —— MOBA/FPS架构篇
随着对战类网络游戏越来越热门,我们解决方案架构师团队也总结行业经验,推出了这套AmazonGameTech架构最佳实践系列,今天给大家带来的是MOBA/FPS架构篇:
FPS/MOBA 的架构由大厅和周边组件和战斗环境组合。具体架构如下图所示:
大厅和周边组件服务
大部分游戏战斗以外的功能,包括商城系统,聊天都属于延时不敏感的操作,一般会选择延时可接受的区域进行多可用区部署,由于大厅为核心服务,建议对功能模块进行模块化和解耦处理,并且利用Autoscaling Group进行弹性伸缩,尽量保证核心服务的无状态化,将缓存存储到Elasticache中。
数据库层面,关系型数据库建议采用支持副本弹性伸缩功能的Aurora mysql 以及非关系型的高性能数据库 DynamoDB,可以利用Elasti cache优化数据库的读压力。
匹配及战斗服务
由于大部分FPS/MOBA 游戏属于延时要求极高的游戏类型,因此大部分战斗环境的部署需要就近和玩家互通,需要部署在全球多个区域。匹配逻辑和战斗环境的弹性伸缩可以使用GameLift来实现。
机型选择
FPS类游戏
大厅和周边服务一般为无状态,较为轻量的服务,可以选用基于arm架构的Graviton2(m6g)或者intel架构的机型(m6i)
战斗环境大部分FPS游戏都会选用帧同步和DR状态同步的混合通信机制,对内存需求会比较高,建议使用m6g或者m6i,选型还需要关注开发语言,如果用go等新型语言开发对Graviton2兼容性较好,如果使用C++等传统语言,还是建议选用intel架构的机型,目前新版编译器也可以支持arm架构的Graviton2机型。
MOBA类游戏
大厅和周边服务一般为无状态,较为轻量的服务,可以选用基于arm架构的Graviton2(m6g)或者intel架构的机型(m6i)
战斗环境大部分MOBA游戏都会选用帧同步通信机制,在同步帧是会需要大量的CPU和网络吞吐,建议使用c6g或者c5,选型还需要关注开发语言,如果用go等新型语言开发对Graviton2兼容性较好,如果使用C++等传统语言,还是建议选用intel架构的机型,目前新版编译器也可以支持arm架构的Graviton2机型。竞技类游戏可以根据战斗环境的具体机制来选择。
数据库
概述
FPS/MOBA游戏,因为匹配对战类游戏属性,战斗环境往往和数据库是没有交互的,主要和数据交互的组件还是大厅及注册,登录,充值等业务模块。根据业务类型,注册、登录及充值系统由于属于强关系和事务属性,更适合使用关系型数据库建议使用Aurora MySQL来提供弹性伸缩和更高的读写性能。大厅角色数据为弱关系型,数据量也相对较大,更多适合key-value的数据库,并且往往要求有强一致性,建议使用Amazon DynamoDB来使用。并且考虑到降低整体数据库压力,可以用Elasticache for Redis来分担相同数据读取压力,如果部分数据有持续化的需求也可以使用Amazon MemoryDB for Redis来替代Elasticache for Redis。
Aurora for MySQL
Aurora for MySQL是亚马逊云科技自研的新一代完全兼容mysql语法的关系型数据库,具体原理如下图所示:
Aurora for MySQL的优点:
- 专为数据库设计的日志结构分布式存储系统
- 存储卷跨分布在 3 个不同可用区的数百个存储节点
- 六份数据,每个可用区两份,防止可用区+1级别的故障
- 离散的IO,减少瓶颈,提供同规格MySQL RDS 5-10倍的吞吐性能
- 读副本弹性伸缩,可支持多写实例,并且在写实例出现问题时会主动提升只读实例为写实例,解决普通关系型数据库的写入单点风险
RPO( Recovery Point Objective,数据恢复点目标)为0,仅数分钟的RTO( Recovery Time Objective ,恢复时间目标)
Amazon DynamoDB
Amazon DynamoDB是亚马逊云科技自研的支持key-value方式的nosql数据库,可进行针对读写容量的弹性扩缩容,并且支持写的流日志,来审计和回滚。利用primary key和sort key的hash进行数据分片和查询数据寻址。
FPS/MOBA适合DynamoDB的技术场景:
- 从数据库调取所有玩家的资料(Key-ValueGet)
- 从数据库调取玩家的拥有的装备和属性(SortKeyQuery)
- 进行对战(纯内存操作)
- 对战完成后,结果更新到角色数据库中(KeyValueUpdate)
DynamoDB的优势:
- 同时支持强一致性和最终一致性
- 基于primary和sort key的读写弹性扩缩容,以及支持按需模式来应对突增的读写请求模型
- 毫秒级别的读写和0客户运维负担
- 流日志记录方式供客户审计需要,并支持持续备份(PITR)以及按需备份
Amazon Elasticache for Redis/Amazon MemoryDB for Redis
Amazon Elasticache for Redis是亚马逊云科技完全兼容Redis协议的内存缓存,并且支持pub/sub来实现队列。Elasticache for Redis 拥有两种模式(集群模式,主备模式)。在FPS/MOBA场景中主要用于数据库读缓存,大厅的消息队列以及计算程序的有状态数据的共享和存储。针对SLA要求较高的数据,可以使用MemoryDB进行持久化保存。
优势:
- 多可用区部署及容灾,以及跨区域复制,并支持计划快照
- 单个集群支持超过250个节点,超过170TB的内存空间,可支持每秒5000万的读,并支持最新的Gravinton2实例,提供更高的性能
- 集群模式支持横向扩展和重新平衡,所有模式都支持纵向扩展
- MemoryDB同时还支持数据落盘和持久化
- 单个集群支持超过250个节点,超过170TB的内存空间,可支持每秒5000万的读,并支持最新的Gravinton2实例,提供更高的性能
FPS/MOBA类型游戏大厅服
大厅服功能模块介绍
FPS/MOBA类型的游戏通常分为大厅服和战斗服,玩家在进入战斗之前和战斗结束之后都停留在大厅服,在大厅服中玩家可以查看自己角色的信息,和好友之间互相聊天、组队,查看战斗回访录像,进入商城购买喜欢的道具与皮肤,查看自己战绩排行榜,匹配其他玩家开启一局对战等。
为了支持玩家所需要的各种功能,大厅服包含了大厅、消息通道、聊天、排行榜、匹配、商城等功能模块。
- 大厅主要用于承载玩家的连接,获取玩家角色状态信息
- 聊天用于玩家之间的文字语音交流
- 排行榜用于显示所有玩家的排名情况
- 匹配用于玩家、玩家队伍之间的匹配
- 消息中枢是大厅和其他功能模块之间通信的中间桥梁
亚马逊云科技上推荐部署架构
- 消息队列可以使用Amazon Elasticache 的pub/sub功能
- Redis使用Amazon Elasticache 或者MemoryDB
- 匹配服务可以使用Amazon Gamelift 的Flexmatch
- 非关系型数据库可使用DynamoDB,DocumentDB
- 关系型数据库推荐使用Aurora MySQL
弹性伸缩
大厅服中的大厅、匹配、排行榜、聊天、商城等模块都可以设计成无状态的,因此可以利用AWS的弹性伸缩功能,针对CPU、内存或者业务指标进行监控,在业务高峰期间,自动扩展更多的EC2以承载玩家流量。随着业务逐渐降低,自动关闭部分服务器以节省成本。在服务器遇到故障的情况下,弹性伸缩也会自动拉起服务器用于容量补充。
Spot
Amazon EC2 Spot 实例让您可以利用 AWS 云中未使用的 EC2 容量。与按需实例的价格相比,使用 Spot 实例最高可以享受 90% 的折扣。同样的,由于大厅、排行榜、聊天等模块可以使用Spot实例类型。在实例有被回收的风险时会发出警告,让业务有充分的时间切换到容量更多的实例类型上。当实例确认将被回收时,会提前两分钟发出告警,业务可利用这段时间优雅终止接受流量。
容器化部署架构
容器化部署的好处
- 管理简便
- 通过容器编排工具,可轻松管理大量的容器,快速复制和分发,实现秒级开服;
- 资源隔离
- 可独立规划和配置每个容器的资源,做到互不影响;
- 高度弹性
- 结合监控工具和容器编排工具,可实现全自动化的容器分发和回收,快速弹性伸缩资源;
- 研运一体
- 结合 CI/CD 工具,实现研发和运维的一体化和自动化,一个版本就是一个容器镜像,开发、测试、打包、部署一气呵成,促成研发与运维紧密协作,极大提升效率,让游戏得以快速迭代;
Amazon Gamelift 如何帮助开发者管理对战服务器
游戏战斗服从过去的网状对等网络模式(P2P,peer to peer)发展到现在的专用服务器为主模式(Dedicate Servers),大大帮助我们提升玩家的游戏体验,解决网络对战游戏的稳定性和连接性问题。
而且,DedicateServer 模式,计算和同步可以放到服务端完成,这样能够非常好的解决游戏外挂和作弊的问题。
Amazon GameLift 利用 AWS 全球基础设施来管理游戏服务器。将玩家匹配到游戏会话中并自动扩展(即同时启动一个、数百个甚至数千个实例),不必思考如何根据波动的玩家需求进行扩展。
开发游戏的时候可以把gamelift进行集成,后端服务器管理就基本不需要花太多精力,服务器资源管理和弹性扩容两个问题就可以轻松解决了。
理想的Matchmaking秘诀我们需要良好的游戏匹配体验那就是对局平衡和等待时间; 理想的对战体验,我们需要服务器扩展性和较低的延迟。
这部分我们可以通过Lambda+DynamoDB生成对战匹配ticket传输到队列服务SQS中,然后开发者可以使用前文提到的大厅服ECS/EKS 服务部署自己的匹配程序,从SQS中获取player对战队列。
当撮合好一局游戏后我们可以向Gamelift发起一个分配对战session的请求,Gamelift 会根据最佳的策略分配给匹配服务最佳的IP和端口,我们将session信息和players信息返回给游戏客户端,玩家就可以通过客户端直接连接到Gamelift提供的对战服进行游戏了,这个过程中Gamelift会始终监测对战session。
在游戏对战的过程中,我们往往会收集一些对战的数据和服务器log进行分析和监控。如下图,客户端log我们可以使用APIGW+Lambda 通过http的方式聚合写入Elasticsearch,服务端log我们可以通过在服务器镜像加入日志收集工具,Fluentd或Fluent Bit等。在准实时和非实时数据收集和分析上,后文数据分析部分会有更多介绍。
当游戏对战结束后,Amazon Gamelift 的游戏程序可以将session进程回收或者删除,游戏结束后我们可以将对战结果通过http的方式回传到数据库中,然后在通过大厅服在游戏结算界面将大家的成绩和奖励进行展示。
就此,我们就完整的完成了一局对战的全流程,从大厅到战斗,我们可以快速通过亚马逊云科技的各项服务进行快速开发和部署,帮助各位开发者专注制作游戏本身。