游戏运营架构设计

这里针对的是滚服系列游戏运营架构设计, 最近看到公司项目的时候想起来类似架构, 所以就顺路整合一下

一般来说滚服类似的游戏架构有几种特点

  • 数量多: 滚服合服的时候, 单个游戏几百几千的区服都是正常

  • 跨区域: 服务器机房并不是固定特定地区机房, 而是分布搭建(需要和游戏服务端相同网段)

  • 数据独立: 数据库是分布的数据库(甚至多个不同云服务器), 不一定采用相同云服务端数据库

  • 统一管理: 代码模块同步是直接大规模部署服务器, 需要用专门的部署来自动化运维

比较小的游戏运营架构直接简单云服务器+云数据库, 最多维护下集群和读写分离就差不多能够稳定运行

simple

这种模式一般时候快速上线轻度小游戏之类, 可以直接将服务器托管给云服务器提供商降低运维成本

度过初期发展之后就会出现渠道服这种情况, 这部分情况是很复杂的, 比如上架游戏的服务器会让你选定指定旗下服务器

比如常见的上线微信小游戏系列的话会买腾讯云, 而部分自有渠道比如华为应用商店这种渠道服也会尽量买相关服务器

那么问题就来了, 云服务就会开始分裂出来出来管理, 那么游戏运营后台不可能直接联通到其他相关服务器

虽然直接开放数据库公网访问就可以解决服务器跨机房分布问题, 但是带来的安全隐患远超过提供的便利

也可以采用数据库白名单连接机制缓解这种问题, 让运营后台服务可以连接上不同云服务机房数据库, 如下所示

advanced

这里将 客户端API游戏服务端 专门整合成独立的服务管理并连接各自云服务, 渠道服部署多少都没有什么关系

而运营后台这是独立服务器通过白名单连接到数据库来加载不同的业务数据服务(不同渠道服的玩家/充值/日报等信息)

注意: 游戏区服不是单台服务器部署单游戏服务端, 而是高性能服务部署多个游戏进程/API服务共享的 游戏服务组

比如 5台16核心32G内存 服务器就是每台服务器部署 5~10 个游戏服和API服务进程, 合计 5台服务器搭建 25~50 个游戏区服

不过也就在这种情况在大规模滚服游戏的时候就会出现问题, 具体最大问题如下

  • 配置同步: 涉及到某个游戏服务器云服务器修改数据库的时候, 需要手动同步给运营服务器的数据库信息(包括重新加入IP白名单)

  • 访问限制: 虽然能够设置IP访问, 有时候运营服务器是大范围部署多个服务器来架设, 每次更新运营都需要手动设置白名单IP

  • 服务拆分: 有时候需要用专门部署后台守护任务来运行异步功能(导出数据报表等操作), 这种情况又要给专门服务加额外加白名单访问

  • 业务压力: 大部分情况数据库查询业务都是集中在单一的运营服务器, 这种情况下查询处理数据的压力都在运营服务器上

所以演变到现在就演变到目前比较广泛的如下架构分层:

  • 游戏服务层: 核心的游戏服务端, 用于提供游戏相关服务和 GM 命令网关服务

  • 数据接口层: 暴露给客户端的接口数据业务, 用于提供第三方授权/支付/游戏公告等功能

  • 数据单服层: 暴露给运营的数据查询数据库业务, 按照不同区服部署各自部署内部业务暴露给中心服查询, 负担部分后台异步脚本功能

  • 运营中心服: 后台管理推送给数据单服务命令, 让单服去查询绑定的云数据库并且执行业务清洗数据并将数据响应回来, 本身不做任何界面展示

这里采用 数据单服 来替换掉原来运营中心直接访问数据库, 并且负担部分游戏数据清洗的处理, 分散掉运营中心服的数据处理压力

business

主要让 单服中心服 做数据交换, 完全不用直接和云服务设备做底层服务连接, 严格来说就是 远程调用 的服务架构

中心服 必须要让后台用户选定 单个服务器来查询中心服记录的服务器关联表 读取远程服务地址, 从而转发查询请求来拉取数据

具体运营后台的查询数据流程如下, 大部分情况下运营服务器只需要和单服做请求处理:

  1. 运营管理员选中单个服务器查询数据: 比如查询游戏的 101 服玩家列表

  2. 运营服务器查询自己的数据库绑定远程地址: 比如查询数据库服务器表 ID=101 的远程服务器地址(single.game.com/101)

  3. 将运营服务器GET/POST请求参数重新打包发送给远程单服: 内部需要追加参数验证签名和白名单机制来放行指定服务请求

  4. 游戏单服去查询自己所属的数据库并且处理数据, 处理完成之后响应返回运营服务器

可以看到这种方式能够有效将处理数据压力分摊到各自 游戏单服, 并且屏蔽掉大部分底层设施(MySQL/Redis/MongoDB等)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
开始

1. 运营管理员在后台选择101服,提交玩家列表查询请求

2. 运营后台前端将请求发送至运营中心服

3. 运营中心服查询本地服务器关联表,获取ID=101的数据单服地址

【判断:查询是否成功?】
├─ 否 → 返回"服务器不存在"错误给前端 → 结束
└─ 是 → 4. 运营中心服重新打包请求参数,生成API签名和时间戳

5. 运营中心服通过 gRPC/HTTPS 向 single.game.com/101 发送请求

6. 数据单服验证请求签名、时间戳及IP白名单

【判断:验证是否通过?】
├─ 否 → 返回"请求非法"错误给中心服 → 中心服转发错误给前端 → 结束
└─ 是 → 7. 数据单服查询本地MySQL/Redis数据库,获取101服玩家数据

【判断:查询是否成功?】
├─ 否 → 返回"数据查询失败"错误给中心服 → 中心服转发错误给前端 → 结束
└─ 是 → 8. 数据单服对数据进行清洗和格式化,转换为统一响应格式

9. 数据单服将处理后的数据返回给运营中心服

10. 运营中心服接收并验证响应数据

【判断:响应是否正常?】
├─ 否 → 返回"服务器响应异常"错误给前端 → 结束
└─ 是 → 11. 运营中心服将数据转发给运营后台前端

12. 运营后台前端渲染玩家列表页面,展示给运营管理员

结束

日常业务除了这种单服选择之外, 还有复选多个服务器来合并统计查询的情况(比如每个游戏区服的玩家注册数量和登录统计查询)

这种情况就是反向让 运营服 需要通知 游戏单服, 让 游戏单服 运行后台统计任务结果然后发给 运营服 写入数据库

也就是复合多个游戏单服数据其实是 运营服 通知 游戏单服 上报保存到 运营服 的数据库之中

这种异步通知上报机制可以有效处理大部分多个游戏区服的复杂条件汇总统计数据, 也是滚服游戏经过考研采用比较多的运营端设计架构

后面性能要求高的情况, 也可以将 HTTPS 成转化成更加底层 TCP 服务(gRPC这套方案)