独立小桥风满袖,平林新月人归后。
一次游戏服务器编码规则制定的经历
角色id的更改
游戏角色的id是根据platform+serverId+十三位自然增长的数字拼接而成。一共有19位,但是运营表示这太长了对客服和玩家太不友好了,所以希望将其更改为10位。这样的需求显然是合理的。当时有两种方式一种是将19位数字转化为32进制。但是考虑到子母的发音辨识度低所以舍弃了。第二种是专门为角色id设计一种短id,提供给游戏外部的人员使用(客服,运维等)。
游戏内部之所以采用这种长编码方式,是因为追求统一的id管理,游戏内部的所有id都是通过同一种方式获取。
这种追求统一的处理方式虽然简洁,但是也付出了很大的代价。第一是角色id过长对玩家不友好。第二游戏内部很多时候id申请都是临时的,这些id并不需要全局唯一,这样导致id很快就被消耗殆尽。但是十九位已经是long型极限了。采用更长的id会增加服务器的负载压力。
这个问题的根源在于在追求统一的过程中,没有考虑到编码所需要的特性。比如角色id需要提供给人取阅读,所以需要可读性。只有很少的id是需要入库的,许多怪物都是刷新之后立即被打死了,所以id的需求量很大,但是不入库的id是不追求永久性的id唯一。
- 采用了短id之后有出现了新的问题:编码不统一,但是代码是按照同一的方式来处理,兼容性弱。
在采用了短编码的方式之后,新增了一系列问题。从id到角色的映射关系要做两套。从客服运营到游戏内的长id都要从短id转一遍。我在做情缘榜的时候需要隔一个小时输出一份排行榜详情,然后我就顺其自然的输出了长id,后来我突然想起来要给别人看必须输出短id。这都是两套映射关系带来的问题。
第二个问题是我自己的问题。我在设计短id的时候想到要用十位,所以用了int。很明显数值越界了。
- 我对这个问题的看法是追求统一的编码方式的总思想是没有问题的,关键问题在于抽象出同的部分。游戏内部期望的是编码的值类型统一,比如都是string或者long。至于编码到底是十位还是十九位,游戏内部出了编码容量以外,没有地方用到编码长度的信息。所以可以允许角色id和其他id的长度不同。只需要有两套接口即可。这个问题想的更深一些是如何抽象相同的部分。在抽象的过程中要仔细考察面对的事物的各项特性,比如角色id就有可读性的要求,怪物id就有量的需求。但是这些对象都需要一个id来区分。游戏内部对id有逻辑简洁的需求。编码规则一旦制定改动成本极其高昂,所以有不变的需求。等等诸如此类的特质都要尽可能深的考虑。
服务器命名规则
服务器在测试期间经常要提供给不同的人群使用,比如测试,运维,运营,客服,支付sdk,策划等,这些不同的人群需求特性分析下来有如下几点
测试需求方便测试各项功能,所以要求有gm,能改服务器时间。
- 运营需要调整各项数值,而且需要数值更改后能及时的反映在游戏中。
- 客服和支付sdk属于外部系统接入,一般需要通过外网访问,还需要代码调试编写等。
- 策划需要体验游戏内的各项功能,所以要关闭GM以防别人干扰其体验。
- 外部审核系统需要一个稳定的服务器,不希望一直重启。但是他们对细节和bug不关心。只关心游戏流程是否顺畅,审核的内容是否正常即可。
- 临时人员的需求,比如商务,行政等人经常临时需求开一个服,且服务器列表只有一个。他们的需求很多时候是临时的用一会儿就再也不会用了。但是他们不希望服务器重启。
- 一般需要备用一个和线上服务器一模一样的镜像服,以便bug查找,热更测试等,所以需要一个镜像服。
- 手机游戏一般会区分安卓和ios,他们的付费系统一般是不同的,ios的付费性要好一些。
- 综上所述,提出如下解决方案:
服务器名称 功能 人群 gm 频繁重启 需要外网 安卓QA 安卓功能测试 QA 是 是 否 苹果QA 安卓功能测试 QA 是 是 否 安卓体验 安卓体验 运营,策划 否 否 否 苹果体验 苹果体验 运营,策划 否 否 否 安卓线上镜像 镜像 研发,QA 是 否 否 苹果线上镜像 镜像 研发,QA 是 否 否 客服日志 功能开发 研发,客服研发 是 是 是 支付测试 sdk接入 研发,sdk研发 是 是 是 安卓审核 审核 外部审核人员 否 否 是 苹果审核 审核 苹果审核人员 否 否 是 安卓渠道测试1 渠道测试 渠道人员 否 否 是 安卓渠道测试2 渠道测试 渠道人员 否 否 是 安卓渠道测试3 渠道测试 渠道人员 否 否 是 备用服务器1 未知 渠道人员 否 否 是 服务器备注规则
- 服务器备注一般提供给研发和运维使用,需要提供服务器的配置,地址,登入方式等。
机器名 | 配置 | 内网ip | 外网ip | 用途 | 登陆方式 【密码:x】 |
---|---|---|---|---|---|
lhrgss | 8核32G | 1.1.1.121 | 1.1.1.53 | 送审服 | ssh -p 30022 root@ip |
game3 | 8核64G500G | 1.1.1.65 | 1.1.1.194 | 线上服1 | ssh -p 30022 root@ip |
云mysql | 对应服务器 | 6,8,10 | 实例 | rm-uf66prx8 | mysql -hip -uroot -pxx |
- 服务器端口ip规则
- 服务器需要配置每个端口的开放权限,内网ip与外网ip的权限
端口 | 用途 | 绑定地址 | 开放范围 |
---|---|---|---|
11serverId | 游戏服客户端连接 | 外网 | 所有 |
12serverId | 客服与支付 | 外网 | 客服ip+支付sdk出口ip |
13serverId | 游戏服进程 | 外网 | 中央服+Ali其他游戏服的ip |
14001 | 中央服进程 | 外网 | 其他游戏服的ip |
- 服务器id编码
服务器一般区分不同的运营平台,所以用一位platform和四位自然增长的id。
这些区分只需要体现在serverid上即可,不要在配置中分开设置platfrom和serverid,不然其他外部人员很难懂
服务器id | 用途 |
---|---|
19999 | 中央服 |
x0001-x9998 | 游戏服 |
1-997 | 游戏服 |
Platform | 2安卓服,3ios服,4混服 |
例子:40004 | 表示混服0004服 |
- 服务器在运维过程中,需要如下指令
指令功能 | 备注 |
---|---|
关闭进程 | 关闭所有/某个服务器进程 |
暂停服务 | 剔掉所有在线玩家,封禁外部ip |
封禁/解封ip | 开服用 |
同步文件 | 将文件同步到指定或者全服服务器目录下 |
查询封禁状态 | 查询指定服的封禁状态 |
加载配置表 | 热更配置表 |
加载服务器代码 | 热更代码 |
查询/修改最大在线人数 |
- 服务器在运行过程中需要实时监控各项状态,如果超过阈值应该由部署在其他机器上的守护进程发出警告。
监控项 | 监控等级 | 阈值 |
---|---|---|
社交服内存 | warn | 80% |
cpu单核 | warn | 90% |
cpu总核 | warn | 60% |
单个异常 | warn | NA |
内存超限 | error | 70% |
单个异常频率超限 | error | 10次/s |
宕机 | error | NA |