小游戏自发布以来, 微信平台上已经出现了不少现象级的小游戏, 包括跳一跳. 在技术上微信小游戏和小程序的区别是什么? 开发商在开发一款小游戏的时候通常会遇到什么问题? 怎么去规避和解决, 来自腾讯游戏云资深架构师余国良, 将会给我们带来微信小游戏架构设计与开发方向.
微信小游戏的特点是什么?
小游戏最大的特点是去中心化分发以及好友关系链的传播. 这里面会带来很多机遇和挑战, 机遇就是有可能带来爆款, 挑战是以往的经验可能就不适用了, 包括技术上的.
那么微信小游戏的特点对我们的架构提出哪些要求? 这里我列举了两个要点. 第一个是全区全副的需求. 为了充分利用微信的社交网络, 要求游戏是全区全服的. 第二个要求就是在线扩缩容的需求, 因为任何一款游戏都可能成为爆款, 在微信上有几何式的增长, 所以几乎成为刚需.
我们看一个案例, 这个案例是我们腾讯云上一个真实客户的案例. 它的小游戏在上线很短的时间内从几万人飙升到 200 万左右. 这个客户经历了什么? 首先游戏上线之后, 很快发现流量增速迅速, 系统流量不够了, 这个时候我们可以通过云主机在线分配. 但是第一个瓶颈出现了, 当吞吐量达到上线的时候很难进行扩展, 他们连夜进行了调整, 将实际数量迅速扩展到几十个. 但是接下来另外一个瓶颈又出现了, 他们用的数据库也是单数据库, 同样有扩展性的问题. 这个问题可以通过改用集群版数据库来解决. 最终虽然所有的问题得到了解决, 但是耽误了时间也产生了损失, 他们在线人数也出现了比较大的下滑.
通过这个案例我们想说明的是, 我们希望小游戏的架构足够轻, 足够小, 但是重点问题也需要提前考虑, 避免问题爆发的时候产生不必要的损失.
那么我们怎么样来设计架构, 小游戏对我们提出这个要求, 接下来我会从两个层面来进行分析, 首先是计算层面, 再是存储层面.
先看这么一个架构, 我们不妨称之为无状态化的分层架构, 简单说就是按照节点的关系按照架构关系分进行衔接, 然后下面这个节点灵活进行伸缩. 这个架构简单使用应对一般的休闲性游戏也是够用的, 我们看一下它在腾讯云上的追加时间是什么样的. 国际客户端通过 CLB 扩展平衡接入到后台服务, 我们经过 BGT 高防对游戏进行保护, 当出现流量的时候, 高防服务可以对流量进行清洗然后回收到系统中. 我们用不同的弹性制作主来承载不同的服务, 通过内网进行衔接以方便实现动态扩容.
这里用到一些腾讯云的产品我们做一些介绍, 首先是 CLB, 腾讯的 CLB 单集群提供超过 1.2 亿的最大连接数, 轻松应对亿级访问量, 单集群可处理峰值 40GB/S 的流量, 每秒处理包量可达 600 万.
第二个就是我们的弹性伸缩服务 AS, 弹性伸缩服务我们可以在不同的时期对集群的节点数量进行伸缩. 我们的出发策略包括这么几个, 一个是定时策略, 监控告警策略, 手动扩缩容策略. 在腾讯云上, 一千台云主机的平均耗时是 63 秒, 接入弹性伸缩服务以及流动的基础能力, 我们可以很方便的对服务进行快速动态的扩缩容, 第三个就是我们的 BGT 高防服务, 在必要的时候我们可以通过 BGT 高防对于游戏进行保护, 它的特点首先平台拥有 T 级的防护带宽, 然后有精准的算法, 在提供防护的同时我们可以最大程度保障网络覆盖质量.
无状态化分层架构有什么优势和局限性
优势就是可靠性高, 单节点鼓掌不影响整体可用性, 以及另好扩展和收缩. 局限性, 无状态化要求对存储层补写数据. 对于这个问题我们往往把比较高的对象缓存到节点内存中, 这对 LB 就提出一些要求. 因为扩展中需要知道发送给某个对象的发送到哪个节点, 它是要建立对象到节点的流动性关系, 显然通用的 LB 是没有办法做到这一点的.
另外一个问题在这个架构中同时节点没有办法发送请求, 但是对于游戏来说, 我们很多时候希望同时的节点之间发送请求. 比如说我们向好友发送组队邀请的时候, 好友的对象和我的对象不在同一个节点, 那么就需要将请求发送到好友的节点, 然后再转发到好友的客户端.
但是对于无状态化分层架构来说往往就需要通过共享数据, 存在实时性和性能损耗的问题. 为了解决这两个问题, 我们看一下星型的架构. 不同节点之间通过 router 进行剖析, 实现节点之间共融的仪器. 比如说 A 节点中的 Player1 对象要向发送 B 节点中的 Play2 对象发送请求, 邀请, 可以将消息发送到 router,router 再转发到大节点处理之后再发送到朋友客户端. 在这个结构中, 所有的节点都是对等的关系, 中间的 router 可以实现互通, 它是比较灵活. 但是它有一个明显的问题, router 是一个单点, 有容缩小和可扩展性. 建立 (英) 可以实现主备的自动切换, 主节点不行的时候可以切换到节点. 他们之间的连接, 我们可以把多结构连接在一起实现架构的扩展. 比如说 Player1 在 (英) 发送 A 节点, Player 发到 B 节点. 当 Player1 向 Player 额 2 发送组队邀请的时候, 可以将消息先发送到 router1,router1 再转发到 router2, 最终到达 B 节点. router 能够将消息发到对象, 它就要保持全局的这样一个装.
我们看一下 router 做了哪些事情? 收敛链接, 简化内部通信管理, 建立通用的对象陆游机制, 简化游戏开发. 第三通过 router 我们也可以实现负载均衡和广播, router 具有通用性, 可以作为通用的游戏界面.
在扩展性方面, 我们可以在两个层面进行扩展, 比如说可以发现节点不够的时候可以进行添加, 分散相应的 router, 然后加入到系统中来. 当一个达到极限的时候, 我们可以通过副机来进一步做扩展, 添加新的. 假设我们有 0 和 1, 需要添加 2 的时候这个流程可以是这样的. 我们先对 2 进行部署, 当 2 起来的时候, router1 和 router2 可以发现新节点, 并且建立到它的连接. 连接之后 router2 会向 router1 或者 router0 并且将自己的信息同步给 router1 和 router0, 这样就建立了. 当 play2 登录到 router2 的时候, router2 会将信息同步给 router2 和 router0, 这是架构的扩展过程.
这个图是扩展的信息结构在腾讯云的实践, 像比较高的游戏, 比如说坦克大战游戏我们实行多点布局, 比如说华南的玩家可以加入到华东, 广州的 UPC 和上海的 UPC 可以实现内网连接.
下面我们看一下存储层的设计, 我们的目标是建立一个大存储层以满足动态扩容的问题. 我们要满足数据库水平扩展的问题, 如果自己做的话有三种方法. 第一种基于增量区间的分配, 它的由点是可以实现动态扩容, 但是存在性能热点的问题. 因为永远都是访问量最大, 而老分片随着流失出现性能限制的情况; 第二种方法, 根据 ID 的闪电池分散到不同的分片, 没有性能热点的问题, 但是加新的节点的时候, 往往对数据进行单切, 比较难以实现快速自动扩容. 第三种方法就是将两者结合, 可以同时解决两个问题, 需要增加中间的数据路由.
为了简化大存储的设计, 我们可以用一些分布式数据库产品, 比如说腾讯云的 DCDB, 它的原理是通过增加中间的代理层, 到多个物理感, 像复杂性完全封装在代理层,. 这两个图是我们对 DCDB 做性能测试, 第一个图是单分片对比 MYSQL 的性能, 随着 CPU 的核和现存数的增加呈线性增长. DCDB 支持新发现的扩容和现有的扩容. 扩容池系统会自动进行搬迁并且切换相应的流量, 可以做到对业务层进行感知. 我要做的只要在页面中点击几下按钮.
第二个产品是 TCaplus, 特点有三个支持 Protobuf 接口访问, 接口友好, 适合游戏开发, 第二个, 将 Cache 与硬盘结合, 第三村塾空间无上线, 单表最大支持 sotb.TCaplus 目前在腾讯内部得到最广泛的应用, 数百款游戏都是以 TCaplus 作为主数据库, 其中包括王者荣耀, 绝地求生等游戏.
来源: https://cloud.tencent.com/developer/article/1084724?fromSource=waitui