海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

时间:2023-09-04 13:48:02

导语 大哥说。今年手Q游戏的春节红包你来做。那该怎么做?以及怎么做才干让大哥放心?本文从后台的角度出发讲述了这个过程和方法。对于关键的前台部分也有所涉及。

文件夹

  • 1.需求背景

    • 1.1.红包类别
    • 1.2.体验流程
    • 1.3.后台需求
  • 2.需求分析

    • 2.1.礼包列表
    • 2.2.区服信息
    • 2.3.领取礼包
  • 3.总体方案与项目分解

  • 4.需求开发

    • 4.1.功能需求开发
    • 4.2.性能需求开发
    • 4.3.容错需求开发
    • 4.4.监控需求开发
  • 5.系统保障

    • 5.1.系统容灾
    • 5.2.过载保护
    • 5.3.柔性可用
    • 5.4.立体监控
  • 6.演习验证

    • 6.1.灰度演习
    • 6.2.压測演习
    • 6.3.异常演习
  • 7.总结

1. 需求背景

1.1.红包类别

2017 年的手 Q 春节游戏红包共同拥有刷一刷/ AR 地图/扫福三种。例如以下图所看到的:

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

1.2.体验流程

尽管红包分三种,但在游戏业务側这边的体验都是一样:用户得到一个红包卡券。打开后展示一个(刷一刷红包)或者多个(AR 地图红包)游戏的礼包列表。用户选择一个礼包后弹出区服组件,用户确认相应的区服角色信息后会礼包会在 48 个小时内发放到账。体验例如以下:

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

1.3.后台需求

游戏红包的设计容量为入口卡券页流量 80k/s。以上体验流程一共涉及三个后台接口:

  • 礼包列表:用户界面的礼包内容须要依据后台接口返回礼包列表进行排序和过滤展示
  • 区服选择:用户界面弹出的区服组件须要后台接口返回用户区服角色信息
  • 领取礼包:用户点击“确认”button领取礼包。后台进行游戏道具发货

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

2.需求分析

2.1.礼包列表

这个功能使用现有能力比較easy解决。

活动共同拥有十种游戏,每一个游戏有两种礼包:拉新(面向非注冊用户,价值 80 元)/拉活跃(面向注冊用户,价值 20 元),一个用户仅仅能获得这两种礼包中的一种,产品策略同意拉新的用户获得价值较低的拉活跃礼包。反之则不同意。页面展示按用户偏好排序十个游戏。每一个游戏展示一个拉新礼包或者一个拉活跃礼包。

出于减少除夕当前流量负载和柔性考虑,在红包活动前,十种游戏的礼包内容作为前端静态数据已经预先通过离线包/CDN 下发;红包活动时。后台接口依据用户偏好返回的游戏礼包列表,仅仅是提供前端礼包内容进行过滤和排序,失败了也有前端默认的游戏礼包列表,保障用户体验。

过滤:读取存储。用户有注冊的游戏返回活跃礼包,用户没有注冊的游戏返回拉新礼包。

排序:一个两层排序,第一层排序读取存储(key 为用户,value 为用户所注冊的游戏列表)。用户注冊的游戏(拉活跃)排在用户没有注冊的游戏(拉新)前面;第二层排序,对于拉新游戏列表和拉活跃游戏列表内部,使用神盾算法对用户这10款游戏的偏好再进行二次排序。对于外部接口的依赖仅仅有 CMEM 存储和神盾算法接口,这两个接口以及合并这两种数据给出终于的个性化推荐礼包列表接口都能够平行扩容以支持 100k 级别的 QPS。

2.2.区服信息

这个功能是现有能力。

这个角色信息的来源是 IDIP ,但因为该接口较缓慢(2s 左右)且容量较低(低于 10k/s),故后台做了一层缓存。将 IDIP 的区服信息永久性缓存到 CMEM 中。前台也有本地缓存,在实践中,前台缓存命中率为 60%,后台为 35%。多级缓存后走到 IDIP 的请求量仅仅有5%,对 IDIP 影响不大,仅仅须要扩容现有的区服 server 和 CMEM 就可以。

2.3.领取礼包

这个功能使用现有能力解决存在困难。游戏中心日常发货的道具和平台比較多,平台分为 IEG-AMS/MP 两种。MP 发货对于发游戏道具和发 Q 币又是两种接口,故我们在架构上使用 Facade 模式,使用 AMS 作为发货 proxy,屏蔽了底层发货的复杂性。向游戏中心提供统一的发货接口。但比較遗憾的是从AMS 到游戏的发货接口都是同步接口,发货能力较低,发货能力最高的王者荣耀也仅仅承诺了 3k/s 的发货速度。明显不足以直接承受 100k/s 级别的红包发货,故这里的核心问题是须要有一个队列来解决生产/消费速度不正确等的问题。

去年的红包是后台收到发货请求后落地到本地文件返回用户成功,再由一个本机的 daemon 跑落地文件按游戏方所能提供的发货速度进行实际发货,相当于使用本地队列缓冲。

但这个方法存在某台机器挂掉后假设不能恢复会丢失一部分本地的发货数据造成漏发。以及每一个高并发业务都要又一次做这一套东西不方便通用的问题。

从架构上思考。事实上最合理的方案是作为发货 proxy 的 AMS 提供异步发货的能力。将用来解决生成/消费速度不匹配的 MQ 做在 AMS 内部。为业务提供通用的异步发货能力,业务側就不须要考虑发货超过游戏方能力的问题。新业务有相似的场景也不须要又一次开发。

游戏中心是业务側,AMS 是平台側的能力,属于还有一个中心的业务。于是一開始我们准备推动 AMS 做异步发货的能力,这样业务就仅仅要调用发货接口就能够了。非常是方便。但事情并没有想象中顺利,与 AMS 的开发和 PM 开会沟通了几次,异步发货的能力他们也有做技术规划。但年前他们有其他需求要做。没有时间支持。

和 leader 讨论了一下这个能力不妨放在 AMS 做成通用以便以后有相同场景的业务使用,前台也有同学开发过 AMS 功能。能够由游戏中心业务側的前后台同学合作完毕 AMS 异步发货功能的开发,在春节红包中应用,再将这个功能交接给平台側的同学维护,达到双赢的效果。

3.总体方案与项目分解

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

总体方案图如上图所看到的。因为整个项目涉及多方开发。并且模块较多,整个模块的开发周期较长,作为一期开发的话无法跟上基础側卡券的验收和安排的几次演习/压測,故按「大系统小做」的原则,依据模块的重要和紧急程度分为几期迭代完毕,每一期有独立的里程碑目标并达到相应的验收/演习/压測要求:

第一期(方案图左側部分)为功能需求,在 12 月 9 号上线通过卡券方面功能验收,先使用当前的同步发货接口,对性能无特别要求。

第二期(方案图右側偏左部分)为性能需求,在 12 月 20 号上线參加第一次演习。对发货进行异步化改造,要求直接面向用户的外网发货接口能支持 100k QPS 的峰值流量。

第三期(方案图右側偏右部分)为容错需求,在 12 月 27 号上线參加第二次演习,对发货进行对账补送改造。保证发货的可靠性。

第四期为监控需求。在 1 月 6 号上线參加第三次演习。确认各项重要数据的採集,并将採集到的数据展现到一个统一视图上,以便除夕期间值班人员实时了解红包系统的总体执行情况和出数据报表。

4.需求开发

4.1.功能需求开发

核心问题:不同场景的数据一致性

{3.1 后台礼包推荐接口}为用户推荐礼包。用户领取时须要经过{4.1 AMS 外网发货新 OP}校验领取资格,后台的推荐数据必须能和 AMS 的资格校验数据能够对上,否则会出现后台推荐的礼包用户领取时却通只是 AMS 的资格校验导致领取不了的问题。

{4.1 AMS 外网发货新 OP}接口处理的是单个游戏的领取礼包的请求,资格校验操作推断一个用户是否注冊了某个游戏。这个是 AMS 现有的通用功能,数据存储在 AMS 的 CMEM 中。简化描写叙述就是一个 key-value 模型,key 为 uin+appid。value 假设有注冊则为 1,没有则为 0(实际为了节省存储空间,使用 bitmap 桶实现。详细參见号码包系统使用文档)。导入的数据源是产品在除夕前一周提供 10 款游戏的全量注冊号码包,每一个游戏一个文件,文件内容是注冊用户的 QQ 号。

但{3.1 后台礼包推荐接口}接口返回的是多个游戏的礼包列表。须要获取十个游戏的用户注冊状态。假设读取 AMS 现有的接口/存储,会有两个问题:

  • AMS 号码包服务也要承受等同于推荐列表接口 48k/s 的流量,须要进行扩容。
  • AMS 号码包服务调用 CMEM 尽管能够一次请求合并 10 个 key 进行批量读取,但请求到了 CMEM 的 Access 机还是要读取多个 Cache 块,性能并不如单请求单 key 读取。

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

解决方式:同质异构的数据冗余

后台将号码包数据进行又一次组织存储到后台申请的另外一个 CMEM 中,key 为 uin。value 为用户已注冊的 appid 列表。已注冊的游戏推荐拉活跃礼包,没注冊的游戏推荐拉新礼包,这样仅仅须要查询一次 CMEM 就能够得到十个游戏每一个游戏的礼包推荐类型是拉新还是拉活跃。

因为 AMS 和后台使用的是同一份号码包数据。仅仅是应用场景不同,数据组织形式不同,两份 CMEM 数据同质异构。故后台推荐的礼包能够通过 AMS 的资格校验。

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

4.2.性能需求开发

核心问题:用户领取礼包流量远超游戏发货能力

红包活动具有时间短(单场 5~30 分钟)、大用户量參与(1.5 亿+)參与的特性,请求并发高,游戏红包入口流量设计为 80k/s,流经各个模块有衰减也有增幅,终于用户领取礼包请求预估为 96k/s。而游戏方提供的十款游戏总发货能力仅仅有 5k/s(单款游戏最大为王者荣耀 3k/s)。请求峰值接近处理能力的 20 倍。同步调用会导致游戏方发货接口过载。造成大面积发货失败,这个问题怎样处理?

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

解决方式:发货异步化

使用一个缓冲队列来解决生产消费能力不正确等的问题。

用户领取请求到达 AMS 进行基础的资格校验后将请求放入 MQ 中,返回用户成功并告知会在 48 小时内到账。再由后台发货 Daemon 从 MQ 中读取请求,通过限速组件控制保证以不超过游戏方发货能力的速率进行发货操作。

使用的 MQ 是部门近来建设的 RocketMQ,详细參见会员消息队列( RocketMQ )接入指南。

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

4.3.容错需求开发

核心问题:安全发货

三场活动发放的礼包总数估计将近 4 亿,怎样保障这些礼包对于合法用户能都发货到账,不少发也不多发?怎样防范高价值道具被恶意用户刷走?有没有可能内部开发者自己调用接口给自己发礼包?

解决方式:对账补送/订单号/安全打击/权限控制

  • 订单号解决不多发的问题

用户领取礼包的接口{4.1 AMS 外网发货新 OP}调用成功,会为这个请求附带一个 UUID 生成的一个全局唯一的订单号,再放进 MQ 中,{4.3 AMS 内网发货 OP}从 MQ 中取出消息,调用游戏方发货接口前都会先校验这个订单号是否用过,没用过则将订单号以 key 的形式写入 CMEM,再进行发货操作。假设出现对同一个发货消息进行反复发货,则会发现订单号已经用过了不会进行实际的发货操作,保证以订单号为标识的同一个发货请求仅仅会进行一次发货操作

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

  • 对账补送解决不少发的问题

发货失败是不可避免的,诸如网络波动/游戏方发货接口故障之类的问题都可能导致调用发货接口失败。在同步领取环境下。用户能够通过重试在一定程度上解决问题。可是对于异步发货,用户点击领取后发货请求由{4.1 AMS 外网发货新 OP}放入 MQ 中就算成功了,即使后台调用游戏的实际发货接口失败了没有实际到账。用户对此也无感知不能进行重试可是会投诉,后台发货系统必须通过自身的容错保证即使游戏方的发货接口不稳定偶尔会失败,用户所领的礼包能终于到。这里我们使用了对账补送方案。

对账:用户领取礼包调用的接口{4.1 AMS 外网发货新 OP}成功写应发流水,{4.3 AMS 内网发货 OP}调用游戏方发货接口的写实发流水,因为部分消息会堆积在消息队列中,这部分称为队列堆积流水。故实际要进行补发操作的流水由下面公式可得:

失败补发流水= 应发流水 - 实发流水 - 队列堆积流水

因为订单号的存在,能够保证同一个发货请求反复发送也不会多发,对队列中堆积的消息提前进行补发操作也不会导致多发。故当队列中堆积的流水较少的时候,採用应发流水与实发流水的差集作为失败补发流水是合理,仅仅是每一个对账周期会对队列中堆积的消息进行两次发货操作。对性能略有损耗。

后台每一个小时执行一次增量对账功能,检測 MQ 消息堆积量量低于某个阈值,则进行对账操作。截取上次对账到此时的应发流水/实发流水,两者相减得到补发流水。

补送:对对账操作得到的补发流水调用游戏方发货接口进行发货补送操作。

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

  • 安全打击解决高价值道具防刷的问题

对于领奖的请求,都要求都要求带上登录态,对用户进行身份验证,同一时候对于高价值的道具开启安全打击,上报安全中心进行恶意用户校验。防止被恶意用户刷走。

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

  • 权限控制解决内部人员监守自盗的问题

对于发货的机器都要安装铁将军,用户须要使用 RTX 名和 token 才干登录机器,审计用户在机器上的操作行为;

发货模块对于调用方是须要严格授权,调用方须要申请 key,包括程序路径、程序 MD5、部署模块等信息,保证发货功能不被任意调用。

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

4.4.监控需求开发

核心问题:红包涉及多个系统的自有监控,数据收集困难

在监控方面有两个主要诉求:

(1)我们对外提供的服务是否正常?假设有问题,怎样高速地发现问题、分析问题?

(2)实时知道用户在整个系统的行为漏斗模型,每一步的转化率是多少?

游戏红包涉及红包基础側/业务前台/业务后台/AMS/MQ 平台等多个合作方,各个系统有自己的监控系统,数据来源不一致。活动当天一个系统一个系统地收集的话效率太低。

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

解决方式:汇总各个系统的重要数据到一个视图

红包作为一个涉及多个子系统的聚合系统,我们须要一个汇总了各个子系统重要数据的总体视图,才干够较全面地监控业务核心指标,对系统和业务有较全面把控。避免在监控系统中跳转检索而耗费有限的时间。为迅速响应解决问题提供保证。

接口封装:尽管红包涉及的多个子系统。各自有各自的上报方式和监控系统,可是对于重要数据大都有提供 HTTP 形式的查询接口。我们通过封装,将接口的定义统一为 key-value 形式,以(监控项 id,開始时间。结束时间)为 key。value 为(開始时间。结束时间)段内监控id的值之和。

配置化:一场红包活动的监控。能够由一个时间段若干个监控项定义。比方刷一刷红包,时间段为除夕当天 20:00~20:30,监控项为若干页面的点击量,若干礼包的发放量,若干后台接口的请求量,若干 MQ 的堆积量等等。

通过对接口的封装和配置化,新增一场红包活动,仅仅须要添加一个时间段和若干个监控项的配置文件,比方下图的 AR/刷一刷混场/刷一刷专场就是通过 3 个配置文件定义 3 场活动,新增一场活动也仅仅须要添加一个配置文件。并能够在一个视图上灵活切换,相当方便。

海量服务实践──手 Q 游戏春节红包项目设计与总结(上篇)

从上图中我们就能够实时看到实发和应发是大致相等的,队列没有出现堆积。用户在各级页面的转化率,能够非常方便地推断系统的健康状态和分析定位问题。


相关推荐

下一篇 海量服务实践──手 Q 游戏春节红包项目设计与总结(下篇)


阅读原文,本文由

fromSource=gwzcw.59745.59745.59745">腾云阁

授权公布,经社区同意后方可转载。很多其他技术文章,请訪问

fromSource=gwzcw.59745.59745.59745">腾云阁

$(function () {
$('pre.prettyprint code').each(function () {
var lines = $(this).text().split('\n').length;
var $numbering = $('

    ').addClass('pre-numbering').hide();
    $(this).addClass('has-numbering').parent().append($numbering);
    for (i = 1; i ').text(i));
    };
    $numbering.fadeIn(1700);
    });
    });