skynet并不是一个开箱即用的服务端框架,游戏后端在开展业务时,需要根据自身业务特点,合理设计相应的服务端框架。在这里我根据自身的设计目标,写下各方面的选择与取舍。
设计目标
设计一个高性能低成本的游戏服务端框架,兼顾数据一致性与可用性。这里的成本指的是开发成本,维护成本,机器成本的总和。高性能我将其排在考虑的首位,对于游戏来说,流畅的体验至关重要,而且高性能是低成本的必要条件。强一致性与高性能是矛盾的,所以我只需达到最终一致性的目标,这里的最终一致性,也可以进行部分牺牲,牺牲在服务器出现断电等不可抗力故障时,允许丢失玩家部分最新数据,玩家感知上就像一个操作之后游戏就卡住了(可能提示了操作成功)。当然,充值等关键数据时绝对不能丢失。出现这些问题可以进行后续补偿。可用性最后考虑,因为游戏服务在业务上允许停服维护。
服务节点拆分
拆分服务的关注点在于性能,分为 网关服务,游戏逻辑服务,聊天服务,登录与支付服务。登录与支付服务合并在一起,是因为渠道的登录与支付一般是同时接入,并且性能也满足需求。
游戏数据分类
游戏数据分类为 玩家私有数据 与 其他数据。玩家私有数据分为 玩家单表单条数据 与 单表多条数据。其中玩家私有数据最终落地存入mysql, 其他数据只存储在redis中。玩家私有数据如:玩家账号,玩家道具,玩家角色,玩家金币,玩家邮件等。其他数据如:全服邮件模板,公告,公会信息,组队信息,全服BOSS进度,服务器状态,活动等。
数据库选型
选择mysql
skynet游戏逻辑服务组织模式
每个玩家对应一个agent服务(skynet service),用来处理玩家逻辑。
ORM映射
每张表都有一个固定的id字段作为主键,id由redis生成保证自增。每张表都有且只有一个 唯一索引,在 单表单条数据中,唯一索引 为 pid,在单表多条数据中,唯一索引 为 pid + id或者pid + cid 或者 pid + 自定义其他的id
通过sql文件,手动维护 后端 表数据结构定义与mysql的表定义的一致性
缓存选择与缓存方案
缓存使用redis,使用cache-aside模式对玩家数据做全量数据缓存,使用redis消息队列,消息队列中的数据为单条数据的更改,可以算作是数据零散缓存。
消息队列
参考消息队列的文章
热更方案
使用 skynet自带的codecache方案,将数据与逻辑分析,可以很方便的更新agent服务中的业务逻辑代码。 其他的代码需要使用inject方式注入更新。不方便的更新还可以使用灰度更新机制。
通信协议
选择sproto,更加轻量



