手机游戏开发框架设计(一):配置管理-包管理中心
本系列所有文章:手机游戏开发框架设计(前言)
包管理中心
包管理中心是整个配置管理中心的基础,所以与客户端有关的配置都是基于包管理的。
包管理中心可配置每个包的 启动公告 ,实现 停服维护管理 ,这与服务器是否真正关闭无关。
包管理中心还能够提供给客户端需要的服务器列表,实现 服务器故障灵活切换 。
包管理中心按照每个客户端包提供不同的配置信息,使客户端能够实现以包和渠道为单位的细粒度配置。
[TOC]
配置依赖
在新的客户端开发构架中, 所有 的配置信息,都是从配置中心获取的。这里的 所有 包括:
- 客户端要连接的服务器和端口号
- 客户端运行在哪个平台之上
- 客户端接入的 SDK 需要的信息(例如 talkdata 需要传递 tdid)
- 客户端用来证明自己属于哪个渠道的信息
- 客户端在支付的时候需要提供给第三方的信息(例如 IAB 和 IAP 中提供的证明自己账户的 appkey)
- 其他需要的信息
为了做到这一点,客户端需要两个值来表明自己的身份,还需要一个 API 地址来获取配置信息:
证明 你妈是你妈 的唯一身份标识,且不重复
表明包的版本号,用于 在线升级(TODO)
配置 API 地址,API 依赖上面两个值来查找配置信息。例如:http://yoursite/api/config/
这种架构,能够保证客户端的所有信息(版本信息和包ID除外)都是可以修改的,避免了包发出去之后出现配置错误而无法解决的问题。
为了保证信息的安全(不被第三方随意获取到),需要增加一些附加验证信息,此处暂不讨论。
包管理的两层架构
上面已经提到过,包管理中心是整个配置管理中心的基础。若无法区分包,则 支付中心(TODO) 和 版本管理中心(TODO) 都没有基础, 支付(TODO) 和 在线升级(TODO) 则更加无法完成。
包管理仅有两层结构,这是为了避免层级过多导致的混乱。从现有的发行方式看来,两层结构已经足以解决 运营渠道 和 包 的所有问题。
第一层结构是 运营渠道 ,我们使用 Channel ID 来指代它。
用来指定特定的 运营渠道 。每个渠道都有一个唯一的 Channel ID。例如 中国移动 是我们的一个渠道,我们可以使用 CMCC
来代表它。
第二层结构是 包 。我们使用 Package ID 来指代它。
为了推广,一个运营渠道大多数情况下都不会只有一个包,两个包之间只要有任何信息不同,就应该单独分包。每个包都要分配不同的 Package ID 。
在客户端仅保存了 Package ID ,不必保存 Channel ID 。这是因为 [Config API][#configapi] 可以根据 Package ID 查询到 Channel ID 。
在每个 Package ID 之下,可以配置不同的信息。根据 Package ID 的不同,这个包的配置也不同。简单的结构就是如此:
1
2digraph packagecentersimple {
3 graph[rankdir="LR",label="包管理的两层架构(略图)"]
4 node[shape="box",fillcolor="white",color="black"]
5
6 channel[label="Channel ID", shape="doubleoctagon"]
7
8 pid[label="Package ID"]
9 config[label="配置信息"]
10
11 channel -> pid -> config
12}
那么配置信息有哪些呢?在 配置依赖 中已经进行过简单介绍。在这里详细进行分类:
我们接入的 SDK 需要客户端告诉它们一些值,这些值若嵌入到客户端则不方便修改,放在配置中心则不然。
客户端运行在何种平台之上。根据目前的运营状态,可能涉及到的所有平台如下:
- Android
- Windows
- iOS
- iOS Jailbreak
- Web
每个 Package ID ,仅能对应一个 Platform 。即使是同样的名称,同样的打包配置(这种可能性并不高),在不同平台上的两个包,也应该使用不同的 Package ID 。
这个包要连接的服务器的信息。这些信息可能包括服务器 IP 地址、端口号、服务器名称等等。
我们可以根据包的不同为它分配不同的服务器地址,这种设计为 分服分区 提供了便利。
这里仅包含一些通用配置。支付配置信息和版本配置信息都依赖 包管理的两层架构 ,它们的详细配置信息的说明,见相关章节。
详细的关系示意图:
1
2digraph package2tiers {
3 graph[rankdir="LR",label="包管理的两层架构(详图)"]
4 node[shape="box",fillcolor="white",color="black"]
5
6 channel[label="Channel ID", shape="doubleoctagon"]
7
8 pid[label="Package ID"]
9 sdk[label="SDK Config"]
10 plat[label="Platform"]
11 si[label="Server Info"]
12
13 {
14 node[shape="Mdiamond"]
15 Android
16 Windows
17 iOS
18 ij[label="iOS Jailbreak"]
19 Web
20 }
21
22 channel -> pid
23 pid -> { sdk plat si "更多..." }
24 plat -> { Android Windows iOS ij Web }
25 si -> { "服务器IP" "服务器端口" "服务器名称" }
26}
游戏管理
同时可能有多个游戏处于包管理系统之中,我们使用 Game ID 来处理这种情况。
用于区分游戏的身份,每个游戏的 Game ID 都是唯一的。
Game ID 和 Channel ID 既可以是上下级关系,也可以是平级关系。
对于上下级关系,以 Game ID 作为根节点,在根节点下选择可用的 Channel ID ,再在 Channel ID 之下建立 Package ID 。 Channel ID 是允许重用的。
1
2digraph relation1 {
3 graph[rankdir="LR",label="上下级关系"]
4
5 gid[label="Game ID",shape="doubleoctagon"]
6 cid[label="Channel ID",shape="box"]
7 pid[label="Package ID",shape="box"]
8
9 gid -> cid -> pid
10}
对于平级关系, Game ID 可以作为 Package ID 的一个属性存在。也就是说在建立 Package ID 的时候,选择其属于哪一个 Game ID 。
这种关系具体如何选择,取决于数据库如何设计。
1
2digraph relation2 {
3
4 graph[rankdir="LR",label="平级关系"]
5
6 gid[label="Game ID",shape="doubleoctagon"]
7 cid[label="Channel ID",shape="doubleoctagon"]
8 pid[label="Package ID",shape="box"]
9
10 gid -> pid
11 cid -> pid
12}
配置继承
对于 Channel ID 相同的包来说,它们的大多数配置可能都是相同的。为了避免输入时的冗余和错误,配置中心有一套继承机制。简述如下:
- 在 Channel ID 级别进行配置,其中的所有配置自动继承给 Package ID ;
- Package ID 级别的配置的优先级更高,允许其在继承来的配置的基础上进行覆盖、删除和增加。
安全性和可靠性
可靠性上要考虑的因素:
- 所有的游戏客户端启动的时候都会访问包管理中心;
- 若包管理中心不工作,则所有的游戏客户端都无法正常工作;
- 游戏的配置要考虑性能和速度。
安全性上要考虑的因素:
- 除我们自己的客户端或者处于调试状态外,Config API 不允许直接访问;
- 需要一些附加的验证信息对客户端的合法性进行验证。
(本文完)
- 文章ID:2399
- 原文作者:zrong
- 原文链接:https://blog.zengrong.net/post/mobile-game-framework-package-center/
- 版权声明:本作品采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可,非商业转载请注明出处(原文作者,原文链接),商业转载请联系作者获得授权。