作者:闲鱼技术-胖仔
背景
古人云:玩归玩,闹归闹,千万别拿权益开玩笑。抽奖是日常营销活动中常见的业务场景,它能够给我们带来巨大的业务增量,无论是对拉新、留存还是变现,都有较强的正向作用。闲鱼目前已有一套较为成熟的抽奖体系,但是随着时间的推移以及人员的迭代,历史的包袱已经日益沉重,资损的风险也是与日俱增,开发、测试、运营在进行日常抽奖业务搭建的时候,都深刻体会到了很多的痛点。本文主要展开介绍其中的一个痛点:资损风险及解决方案。
*资损:因某些不正确的操作或存在漏洞的代码片段引发的集团资金损失。
资损风险场景
一个常规的抽奖需求往往需要运营、测试、开发三方的参与,常见的流程如下:
开发风险
对于开发来说,需要开发一个全新的抽奖模块,以便连接底层权益平台和上层页面展示,这个模块除了页面布局、UI样式等基础逻辑,还需要包含权益相关内容,多个模块间可能会包含类似的权益逻辑,比如大转盘抽奖和刮刮乐抽奖,都是抽不同金额的消费券,所以多个模块间可能会进行重复性代码工作,此时往往会有较多的复制粘贴场景,而复制本身是一个高效却不安全的行为,这就给业务场景埋下了无声的地雷,可能某一次不小心的疏忽就导致了潜在的资损。(下图为常见的模块开发场景)
运营风险
对于运营来说,首先要在权益平台进行权益配置,包括但不限于权益内容(如权益类型、投放渠道、投放计划等)、定向配置(如人群配置、前置任务配置等)、活动配置(如活动基本信息、可领次数等)。当完成权益配置后,需要在运营搭建平台进行页面搭建,此时会使用到开发提供的抽奖模块,并进行权益内容的二次配置,搭建平台的权益配置仍然繁琐及复杂,且和UI配置耦合严重,一次发布行为会同时发布页面元素内容和权益配置内容,哪怕只是变动了按钮颜色,也有可能因为权益变更引发资损风险。
如下图所示,运营的页面变动有时候是较为频繁的,一旦用户数据不理想,就会进行页面调整实验,比如调个按钮位置、调个背景图片、调个标题文案,而目前UI和权益是强耦合的,所以每一次变动,都有引发资损的可能。
测试风险
对于测试来说,在进行权益测试时,并没有一个直观的调试界面,当发现权益领取异常后,会联系开发定位,而开发其实也很难进行问题定位,因为模块开发可能已经过去了很久,甚至开发人员已经进行了更替,此时只能从头到尾一点点进行全链路排查,往往会消耗大量的时间,而测试也只能看到最终结果,中间的执行过程是否正常其实并没有办法进行定位,这其实是不安全的。
运行风险
对于线上正在运行的抽奖业务,目前并没有完善的对账和监控体系,也就是说,目前缺少问题自动追踪和自动告警的能力,如果出现异常,会比较被动,解决问题的时间会大幅拉长,用户投诉的次数会显著变高。
解决方案
其实上述流程存在的一个关键问题就是冗余,权益逻辑不仅在权益平台进行配置管理,还会在多个抽奖模块、多个抽奖页面进行大量重复性配置,在多人协作和工作交接的过程中,风险就会不断地上升,所以解决问题的核心,就是要剔除不必要的冗余,做到风险隔离,权益收敛,统一入口,详细方案如下:
权益独立管理
针对运营的变更风险,我们将所有的权益逻辑从原有的搭建体系内抽离,在新的平台上进行统一权益管理。在页面搭建层只暴露权益ID,通过ID衔接整个抽奖流程,运营在搭建页面时,可以只关注页面内容配置,而不再需要关心权益逻辑,单次发布只会影响UI展示,而不会影响底层权益逻辑,可以极大地降低页面变更风险及新人学习成本。
为了最大程度的保障权益安全和责任定位,我们实行了严格的权限控制,只有创建者才能进行权益变更,他人可进行权益查看、权益拷贝等,但无编辑、删除权限,以防他人的误操作引发不必要的麻烦。且权益的变更不会立刻同步到线上,默认会变更到预发环境,在进行测试回归正常后才可进行上线操作。流程示意图如下:
提供抽奖SDK
解决代码冗余最佳的方案就是做纯逻辑抽离封装,针对闲鱼大部分抽奖场景和抽奖类型,我们进行了抽奖SDK的统一封装。抽奖SDK连通了底层抽奖服务和上层业务应用,提供了一键接入方式,并且完全兼容常规h5及weex环境。
接口设计:抽奖常见的需求就是抽奖资格查询、抽奖状态查询和执行抽奖行为,所以我们提供了如下接口:
- isDrawing: 是否正在进行抽奖,用于判断此次抽奖行为状态
- canIDraw:可一键查询该用户是否符合抽奖条件,以便与展示不同的页面元素
- draw:执行抽奖,返回Promise对象
- mockDrawData: 模拟抽奖行为
- mockDrawFail:模拟抽奖失败
为了最大程度地减少业务代码量,我们隐藏了所有关于权益的底层调用,让抽奖逻辑更加抽象化、更加语义化,常见的使用方式如下,开发可以通过抽奖SDK快速对接权益运营平台,不再需要关心底层权益逻辑,大大减少了代码成本和操作风险。
// DEMO演示
// 复杂的权益逻辑都将收敛于 fin-olivier 中
import Olivier from '@ali/fin-olivier';
const olivier = new Olivier({ activityId: 12345 });
// 判断抽奖资格
olivier.canIDraw().then(() => {
// 执行抽奖
olivier.draw().then(() => {
// success
}).catch(() => {
// error
});
});
日志回流展示
为了缩短测试路径、加快问题定位,我们提供了实时日志功能,在权益管理平台可通过扫描二维码查看实时日志回流,用户的每一次操作,都将拆分成极小的粒度进行监控和统计,可以非常直观地看到每一个子节点的状态和说明。
如下图所示,一个完成的测试链路为:在运营平台扫码查看权益页面 -> 在权益页面进行抽奖行为 -> 抽奖服务自动上报各节点日志到日志服务 -> 日志服务自动推送日志到权益管理平台 -> 测试可在权益管理平台查看可视化日志。如果某个节点出现异常,会自动高亮并给出详细异常原因。可观测粒度更细、更直接,有利于开发和测试的问题定位和排查,大幅提高效率的同时也提高了一定的安全性。
对账 & 监控
除了完善上线前的稳定性建设,上线后的稳定性同样重要,就此新增对抽奖各个环节的监控和日志统计,各个监控点如下图所示,当监控出现报警时会自动提醒相关责任人,以求最快的速度定位并解决问题,运营也可以在报表平台查看监控报表,从而可以更直观地查看线上活动的运行情况。
效果
针对之前所阐述的风险点,已经有了明显的成效:
- 我们抽离了权益相关的概念,页面搭建时所需配置的内容明显减少,平均配置时间减少50%+。
- 搭建页面时不再涉及权益逻辑,抽奖安全性大幅上升,页面变动发布零风险。
- 通过日志回流功能使得测试链路变得更加简单、更加直观,测试沟通成本由0.5人天降为0人天。
- 新增线上对账和监控,24小时保障线上安全。
- 通过抽奖SDK给前端模块瘦身,开发可一键接入权益平台,无风险更高效。
总结
在业务日趋成熟和完善的当下,稳定性俨然成为了首要考虑的问题,今年闲鱼团队也做了很多方向的稳定性建设,抽奖只是多个稳定性建设中的一环,我们致力于打造绝对安全、无线上故障的闲鱼技术生态。
目前抽奖稳定性建设已完成并逐渐对外开放,未来闲鱼权益体系都将收敛于该平台中,老的体系和已上线的业务不再更新,新的业务需求都将对接新的抽奖体系,后续在不断地使用过程中也会持续优化,我们希望我们的抽奖平台能够服务于所有闲鱼业务甚至淘系业务。