相关阅读:
1.7亿DAU背后,《跳一跳》踩过了那些坑(上)
开年以来,小游戏一直是行业所关注的全新领域,作为小游戏代表的《跳一跳》更是用其1.7亿DAU惊人的成绩牵动着整个行业的目光。
在昨天下午举办的“小游戏 大能量”微信公开课小游戏·产品专场上,《跳一跳》研发团队就《跳一跳》在研发过程中在性能、网络和后台反面遇到的困难和其应对的“突围之道”进行了分享。
龙虎豹在活动结束后第一时间对其内容进行了整理,由于干货内容过多,将分为上下两期进行推送,此处为下期。错过上期的读者请点击《1.7亿DAU背后,〈跳一跳〉踩过了那些坑(上)》。
以下为现场实录。
后台:轻量架构 稳定游戏
大家下午好,我是微信公开课讲师梁国秋。
接下来由我给大家分享一下《跳一跳》接龙模式后台的状况。
《跳一跳》接龙模式是在今年春节的时候推出的基于《跳一跳》单人模式玩法创新的多人模式玩法,玩家可以创建自己的房间,并且把自己房间的信息通过群卡片或者线下小程序码的方式分享给自己的好友,邀请他们一起来进行游戏。
那么对于整个游戏的架构是如何去设计的?下面请允许我通过三个方面为大家一一介绍。
第一个方面是后台架构是如何去进行设计的,第二个方面是游戏数据同步是如何进行的,第三个方面是如何处理异常的。
首先来看一下我们的后台架构。刚开始去改造多人游戏模式的时候,我们选择了很扁平的一个四层模型结构,具体是哪四层?
第一层是我们的客户端层,这里客户端层一般就是手机端;第二层是接入层,是连接客户端层和后台逻辑层的一道桥梁,负责把用户的指令信息传输到后台服务器;第三层是游戏逻辑层,游戏逻辑层负责进行游戏逻辑的计算;第四层是无论对单人游戏还是多人游戏都很重要的存储层,假设单人游戏中我们想做排行榜的展示,那么这里就必须得把用户的分数保存起来,于是就需要有储存层,在多人游戏中,相对而言,我们需要保存的信息会更多。
我们一起来看一下多元游戏的后台结构是如何去设计的,可能在这幅图中大家就对整个架构的了解还不够清晰,那么我们换个角度来看一下整个后台结构。这里把整个结架构放开,首先可能存在几个玩家,他们到底是如何去把自己的信息连接到整个流程中,或者说整个数据流是如何去进行运作的呢?
玩家A的数据流会通过路由1到达我们的游戏服务器,游戏服务器会把信息传输给数据库1进行保存,在这整条链路上可以看到,对于整个链路是分别设有路由器1和路由器2,那么为什么玩家A不能去路由器2呢?其实是能够去路由器2的,那他们的存在的又意义何在?其实在后台架构的设计中很容易发现,假设玩家A连的路由1发生了网络问题,导致无法访问,这时候玩家A是不是不能玩游戏了?
在整个后台架构设计的过程中,我们希望无论哪个单点出现意外,整个游戏不会受到影响,所以就必须有路由2,路由相当于桥梁来连接玩家跟游戏的逻辑服务器,当其中一道桥梁出现问题了,还可以通过另外一道桥梁来进行游戏的通讯,在我们数据库1和数据库2也是一样的道理,我们希望他们形成互相备份的保护作用。
整体的一个游戏的架构就是这样,它的好处在于说我们可以互相容载,那这是不是就没有任何缺点了呢?看一下整个游戏的流程流向,从玩家A到数据库1,整个游戏经历了三次转发,从玩家A到逻辑服务器再到数据库,那么我们接下来看一下下一个模型。
在第二个模型中我们把服务器1和数据库1部署在一起,或者说简单来说在游戏服务器逻辑服务器上面直接采用共享内存的方式进行数据存储,这样模型改造带来的好处是什么?
其实大家可以很清晰地发现玩家A到路由器1再到整个存储的时候,只经历了两条网络链路,这就很简单的优化了33%的网络通讯,假设大家在玩高实时的FPS游戏的时候,其实整体的对网络延迟的要求是很高的,在这个场景下,必须得尽量让整个后台架构的网络通信短且扁平,这样延迟会得到大的提升。
至于这样改造之后的缺点大家也看得出来:我们的数据库1跟数据2不能互相进行备份了。在这种场景下,假设我们数据库1发生问题了,它会直接影响到逻辑服务器1的游戏,逻辑服务器1上面的数据不能保存,整个游戏进程在服务器上也就不能继续进行了,这时候只能依靠路由器1去监控到异常,然后并且把玩家A的信息录入到服务器2去继续游戏。
业界内存在一个叫CAP原则的概念,是说在做后台分布式架构的过程中,其实有很多个点需要考虑的,但是没办法兼顾到所有点,那么其实在做一款小游戏的过程中,可以评定一下自己小游戏的适应点。
假设在高实时同步的小游戏下,我们可能会尽量希望延迟会更低,那么在低时使的小游戏设计上,对延迟性要求不高的情况下,我们会希望整个后台架构更加稳定,这样出错的概率会更低。整个游戏后台架构的设计过程中,我觉得找到最适合自己的一款设计就足够了。
接下来我们看一下《跳一跳》接龙玩法的同步逻辑是如何去实现的。当玩家点击多人游戏按钮,首先会为他创建一个房间,并且把这个玩家加入到房间中,然后玩家会成为房间的房主。
具体到后台,玩家A在点击多人游戏按钮的时候,会把创建房间的指令告诉服务器,服务器收到这条指令之后会随机生成一个房间ID,然后把玩家加入到房间信息里面并且记录玩家A是当前房间的房主,再把房间ID返回给玩家,告诉玩家其创建的房间是哪个,这个房间ID跟我们前面所说的玩家需要分享的卡片先不对应。
为什么这里我们要随机一个房间ID呢?假设我有三个用户一起去创建房间,如果他们的房间ID有冲突的话,会导致整个游戏数据或许会发生交错的,为了避免交错的发生,就必须保证说根据每一个玩家创建出来的房间ID都具有玩家的特性,并且是相互平行的关系,而且针对每一个房间,我们希望都具有唯一性的特点,保证数据不会串。
此时,创建完房间的房主,会把自己的房间信息通过卡片的方式分享到群里,邀请群里的小伙伴一起进行游戏,或者说用线下的小程序码给其他玩家扫描,也可以加入到房间中。
那么这里具体是怎么样的一个逻辑?其实在卡片中或者小程序码里都会保存房间ID,当其他玩家点击房间卡片的时候,会获取到具体的房间ID,并且把玩家的信息跟房间ID带到服务器里,然后服务器会根据房间ID去获取整个房间的信息,从而把玩家加入到当前的房间里面。
加入到当前房间后,我们还要做的一件事是通知其他玩家,已经有一个新玩家加入到游戏中了,当其他玩家收到加入房间的广播之后,他们就可以渲染出来整个房间里的所有玩家。
接下来需要做的是开始游戏阶段的同步。这时会仅在房主的客户端显示开始游戏的按钮,当房主点击开始游戏命令之后,会把房间的房间ID和他自己的信息带到游戏服务器,游戏服务器收到这条指令之后会进行校验,如果校验成功,就修改整个房间的状态为运行中,然后告诉所有房间内的其他玩家:游戏开始了,
其他玩家收到游戏开始的指令之后,就会渲染出正常的游戏流程。到这里为止,房间已经创建完成并且游戏正常开始了,接下来就是游戏过程中的同步逻辑。
接龙游戏进入游戏之后,玩家开始点击操作的时候,会把他的指令上报到服务器,那么他跳完之会有一个结果:玩家A跳成功了还是失败了,当结果上报给服务器,会先被保存起来,服务器不会马上相信他的结果,毕竟如果单纯地相信一个玩家A的结果,有可能会出现异常情况。
所以这里引入了另外的概念,我们希望这个结果是所有其他玩家也能同样得到的,所以我们会把房间A的指令也发送给玩家B、C、D,一起去校验其过程。当玩家B、C、D把其完成A的指令算出来的结果上报给服务器的时候,服务器会把所有结果收集起来,做一次统一的校验,当校验出来的结果是完全统一的时候,会载去进行运算,计算下一个轮到的玩家或者下一个游戏状态,然后再进行下发。
其实到这里,我们整个游戏逻辑的流程都已经做完了,是不是整个游戏就不用去做其他修改了?不,还需要修改,大家有没有想过,假设我跟小伙伴一起玩玩一款小游戏的时候,朋友有可能进地铁了或者说收到了电话信息,突然断开了网络,这时候因为断开了网络,我们的服务器也不能去直接问他,你有没有断开是吧?这个时候应该怎么去告诉B、C、D玩家,其实玩家A已经断开了呢?
这里我相信大家都会遇到一个场景:假设我们去开会的时候,通常都会设置一个闹钟,假设会议时一点钟,那么我们就会设置1点钟那种或者说12点半的闹钟提醒我们要提前到达会议,同样原理作用,在后台架构这里其实也可以为游戏逻辑设置一个我们称之为定时器的闹钟。
通过定时器,我们可以去检测玩家A是否已经超时了,如果超时了,服务器就可以自动去运算下一个游戏逻辑的流程推送给其他玩家。具体定时器是如何去运作的呢?玩家A跟服务器之间会发送一条指令,告诉服务器说我要跳了,这个时候我们就会针对这条指令来设置一个定时器,一旦玩家A的这条指令超时了,服务器就会检测当前整个游戏逻辑是否还仍然存在于等待玩家A的这条指令的基础上,如果还在的话,这个时候必须去推进整个游戏的下一步进展。
其实通过这么一部简单的动作,简单的协议,我们就实现了自动定时器的概念。当然其实在《跳一跳》接龙这里,我们是利用了两套逻辑并行的方案去进行的,因为希望我们游戏的逻辑会更加稳定。当我们计算到整个游戏已经超时,会计算下一个游戏流程,并且把它推送给其他玩家。其实它的作用是跟我们的自动定时器是一样的。
今天过来分享,我觉得主要想分享的一个主题是我们如何去设计一个轻量化的架构,就可以保证我们整个小游戏的稳定运行,谢谢大家。
总结
接下来让我来总结一下,这次是《跳一跳》的开发团队,第一次用组团的方式给大家进行技术分享,希望这种模式可以跟大家更深入地了解到《跳一跳》里面的很多技术细节,让大家分享到我们技术的突围之道。
接下来我来总结一下几位同学的思路:性能上,我们通过合并渲染能让整个游戏的性能,从渲染性能、体验以及效果上平衡玩家的体验,能让性能在玩家体验的舒服和游戏顺畅上得到平衡;网络上,网络的复杂度导致了可能有不可避免的错误,通过及时纠错的机制,可以让整个游戏可以顺畅的运行,在网络上面实时可靠是很关键的两个点;后台上,轻量架构能够在拥有庞大DAU的同时,也能让整个游戏可以支撑更大的数据量,让游戏可以更顺畅的进行。
最后,我在这里做一个未来的展望,我的游戏团队,除了刚才分享到的那么多技术经验以外,也在想能不能有一些更多的帮助给到各位开发者,后续我们可能会通过一些开源或者通用服务的方式,能有一种更开放的心态,能助力各位开发者,助力整个生态,让开发者可以做出更多更好的小游戏。
我们团队的分享到这里,谢谢大家。
via:手游龙虎豹