专栏名称: 聊聊架构
在这里煮酒聊架构。
目录
相关文章推荐
美团技术团队  ·  可信实验白皮书系列04:随机轮转实验 ·  2 天前  
字节跳动技术团队  ·  掘金 AI 编程社区- 人人都是 AI 编程家竞赛 ·  2 天前  
51好读  ›  专栏  ›  聊聊架构

从技术角度谈一谈,我参与设计开发的手Q春节红包项目

聊聊架构  · 公众号  · 架构  · 2017-02-26 09:54

正文

请到「今天看啥」查看全文


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

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

接口处理的是单个游戏的领取礼包的请求,资格校验操作判断一个用户是否注册了某个游戏。这个是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读取。

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

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

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

性能需求开发

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

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

解决方案:发货异步化

使用一个缓冲队列来解决生产消费能力不对等的问题。用户领取请求到达AMS进行基础的资格校验后将请求放入MQ中,返回用户成功并告知会在48小时内到账。再由后台发货Daemon从MQ中读取请求,通过限速组件控制保证以不超过游戏方发货能力的速率进行发货操作。使用的MQ是部门近来建设的RocketMQ,具体参见会员消息队列(RocketMQ)接入指南。

容错需求开发

核心问题:安全发货

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

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

1. 订单号解决不多发的问题

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

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

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

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

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

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

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

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

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

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

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

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

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







请到「今天看啥」查看全文