手机游戏开发框架设计(一):配置管理-包管理中心

本系列所有文章:手机游戏开发框架设计(前言)

包管理中心

包管理中心是整个配置管理中心的基础,所以与客户端有关的配置都是基于包管理的。

包管理中心可配置每个包的 启动公告 ,实现 停服维护管理 ,这与服务器是否真正关闭无关。

包管理中心还能够提供给客户端需要的服务器列表,实现 服务器故障灵活切换 。

包管理中心按照每个客户端包提供不同的配置信息,使客户端能够实现以包和渠道为单位的细粒度配置。

[TOC]

配置依赖

在新的客户端开发构架中, 所有 的配置信息,都是从配置中心获取的。这里的 所有 包括:

  • 客户端要连接的服务器和端口号
  • 客户端运行在哪个平台之上
  • 客户端接入的 SDK 需要的信息(例如 talkdata 需要传递 tdid)
  • 客户端用来证明自己属于哪个渠道的信息
  • 客户端在支付的时候需要提供给第三方的信息(例如 IAB 和 IAP 中提供的证明自己账户的 appkey)
  • 其他需要的信息

为了做到这一点,客户端需要两个值来表明自己的身份,还需要一个 API 地址来获取配置信息:

Package ID

证明 你妈是你妈 的唯一身份标识,且不重复

Version

表明包的版本号,用于 在线升级(TODO)

Config API

配置 API 地址,API 依赖上面两个值来查找配置信息。例如:http://yoursite/api/config/

这种架构,能够保证客户端的所有信息(版本信息和包ID除外)都是可以修改的,避免了包发出去之后出现配置错误而无法解决的问题。

为了保证信息的安全(不被第三方随意获取到),需要增加一些附加验证信息,此处暂不讨论。

包管理的两层架构

上面已经提到过,包管理中心是整个配置管理中心的基础。若无法区分包,则 支付中心(TODO) 和 版本管理中心(TODO) 都没有基础, 支付(TODO) 和 在线升级(TODO) 则更加无法完成。

包管理仅有两层结构,这是为了避免层级过多导致的混乱。从现有的发行方式看来,两层结构已经足以解决 运营渠道 和 包 的所有问题。

第一层结构是 运营渠道 ,我们使用 Channel ID 来指代它。

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}

Graphviz chart draft_2-packagecentersimple-0.png

那么配置信息有哪些呢?在 配置依赖 中已经进行过简单介绍。在这里详细进行分类:

SDK Config

我们接入的 SDK 需要客户端告诉它们一些值,这些值若嵌入到客户端则不方便修改,放在配置中心则不然。

Platform

客户端运行在何种平台之上。根据目前的运营状态,可能涉及到的所有平台如下:

  • Android
  • Windows
  • iOS
  • iOS Jailbreak
  • Web

每个 Package ID ,仅能对应一个 Platform 。即使是同样的名称,同样的打包配置(这种可能性并不高),在不同平台上的两个包,也应该使用不同的 Package ID 。

Server Info

这个包要连接的服务器的信息。这些信息可能包括服务器 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}

Graphviz chart draft_2-package2tiers-1.png

游戏管理

同时可能有多个游戏处于包管理系统之中,我们使用 Game ID 来处理这种情况。

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}

Relation1

对于平级关系, 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}

Relation2

配置继承

对于 Channel ID 相同的包来说,它们的大多数配置可能都是相同的。为了避免输入时的冗余和错误,配置中心有一套继承机制。简述如下:

  1. 在 Channel ID 级别进行配置,其中的所有配置自动继承给 Package ID ;
  2. Package ID 级别的配置的优先级更高,允许其在继承来的配置的基础上进行覆盖、删除和增加。

安全性和可靠性

可靠性上要考虑的因素:

  1. 所有的游戏客户端启动的时候都会访问包管理中心;
  2. 若包管理中心不工作,则所有的游戏客户端都无法正常工作;
  3. 游戏的配置要考虑性能和速度。

安全性上要考虑的因素:

  1. 除我们自己的客户端或者处于调试状态外,Config API 不允许直接访问;
  2. 需要一些附加的验证信息对客户端的合法性进行验证。

(本文完)