网页客服,欢迎咨询

通用营销抽奖系统架构设计与实践

2025-01-06 23:05:01 127
  • 收藏
  • 管理
    总篇108篇 2020年第32篇背景营销类业务中经常有一些抽奖活动类的玩法,如大转盘、红包雨、老虎机、摇一摇等。在业务支持过程中,经常遇到需求频繁变更,定制化需求多等问题。?比如某次抽奖需求:1.每个用户都有多次抽奖机会,但每次的概率又不同;2.抽奖活动周期内,为控制预算并保证活动效果,对每天的奖品数量进行控量;3.为应对“非正常”用户,在每天指定的时间段,降低中奖概率;4.……等等的此类抽奖玩法需求,每场抽奖活动形式大同小异,但背后的业务需求又存在差异,定制化程度特别高。早期我们的处理方式是每次都针对需求重新开发,那时需求较为简单,抽奖活动数量也较少。随着业务规模日益扩大,抽奖活动频率越来越高,我们先开发一套简单的配置式后台,支持简单的奖品和概率的配置。但是实际使用中,也有一些问题,比如:1.差异化抽奖规则很多,根本无法通过简单的概率配置,满足业务需求,定制化成本很高;2.对于大型专题中抽奖活动的并发控制、数据一致性等提出很多挑战;3.兄弟业务线也有类似的需求,但基本需要重新实现一遍,系统复用性很低。考虑到以上问题,加之抽奖玩法是一个相对独立、应用场景广泛的业务,于是我们开发一套通用的抽奖系统,提供系统级业务复用的能力,系统单独维护、单独部署,保证通用性和可伸缩性。下面从:系统概述并发控制可扩展性配套设施等几个方面介绍一下这个系统。系统概述为保证整体的灵活性,本系统采用领域模型驱动设计(DDD),对系统中不同业务模块进行抽象:图片1 抽奖请求流上图中的业务概念:活动:抽奖活动的主体,多数场景下,一场抽奖活动就是一个活动对象。轮次:与活动是一对多的关系,例如:一场秒杀活动,可能有多个场次,多个场次可以只报名一次,但每个场次的奖品又不同。类似场景,可以采用多个轮次解决。轮次奖品:多轮抽奖,奖品虽然一样,但是概率不同。于是引入轮次奖品的概念,不同轮次就可以针对同一个奖品,设置不同的概率。库存同理,在轮次+奖品的维度维护其对应关系,而不是直接绑定在奖品上。不同轮次可选相同的奖品、不同的库存。概率组:多条抽奖概率信息,组成一个概率组,如:用户首次抽奖,中奖概率是50%,第2到第5次抽奖,中奖概率提高为70%,于是系统把概率独立出来,并引入概率组的概念。这样就可以在一个概率组里配置两条概率,一条是第1次的概率50%,一条是第2到第5次的概率为70%。中奖规则:描述每次抽奖行为响应结果的方式,比如:活动周期内,用户有3次抽奖机会,但是只能中奖1次,即:之前中过奖,就不能再中。这时通过把中奖规则独立出来,并且在抽奖活动和轮次上都关联中奖规则,这样创建一个抽3次中1次的中奖规则,然后在抽奖活动和轮次都选这个规则,从而实现需求。反作弊规则:抽奖活动经常面临被一些黑产薅羊毛的处境,识别正常用户和非正常用户的成本较高,且较难保证准确。虽然前端可以通过图片验证码、短信验证码等方式来提高门槛,但是道高一尺魔高一丈,还是有被突破的风险。因此本系统引入反作弊规则的概念,在特定用户、时间段等维度,对抽奖行为进行限制。回调规则:作为一个独立系统,其他业务系统调用抽奖后,可能需要做记录中奖信息,发送短信等异步处理,于是加入异步回调功能。业务实体模型如下:图2 实体模型系统实现过程如下:1. 根据设计的模型,为每一个实体定义接口和一个工厂类,通过接口只暴露行为,工厂类依据不同的类型属性,去构建对应的实例。不同类型的实现类可以根据需要使用不同的属性字段去实现功能。2.在进行一次抽奖时,需要明确到某一个轮次,构建一个抽奖轮次,除了轮次数据外,还有抽奖活动、奖品等其他数据,显然多次数据库查询性能肯定不能满足接口要求,因此我们引入自主开发的分布式实时内存缓存组件,提升查询性能的同时,也保证了数据的实时性。3. 当构建好一个轮次实例后,便开始处理抽奖流程,过程依次分为:前置验证、执行抽奖逻辑、后置验证、入库、返回结果五个步骤:A. 前置验证:主要基于Redis,包括抽奖规则验证,风控验证,库存验证。B. 执行抽奖逻辑:根据轮次的轮次奖品集合进行抽奖。实现上,采用离散算法,实现按权重进行抽奖的逻辑,主要包括三种情况:假设有3个奖品P1:奖品1中奖概率P2:奖品2中奖概率P3:奖品3中奖概率random:[0,1)的随机数第一种,概率之和等于1(必中奖的场景):即P1+P2+P3=1,权重恰好与其本身概率一致第二种,概率之和小于1:即P1+P2+P3<1,由此计算出为中奖概率1-P2-P2-P3=0.1,若random落在0.9-1中间,则未中奖,落在其他区间,则命中对应的奖品第三种,概率之和大于1:即P1+P2+P3>1,此类情况则为100%中奖,每个奖品的权重按概率之和的占比计算,如P1的权重计算公式为:P1/(P1+P2+P3)。用实际数字举例:P1权重= 20/(20+40+60) = 0.16,然后取随机数判断中奖结果。。C. 后置验证:由于价值类奖品存在随机问题(如:现金红包有不同金额),只有在抽中之后才会明确价值,因此需要后置验证库存,防止超卖问题。系统设计上,支持活动和奖品共用库存,此处分两种情况,共用库存时,只验证统一库存;非共用时,需同时验证活动库存和奖品库存,此处验证同样基于Redis。D. 入库:保存中奖记录并扣减库存,需保证在一个事务中执行,以保证数据完整性和一致性,同时这里利用数据库锁进行库存扣减,防止库存超卖。E. 返回结果:中奖结果响应包括实时与异步两种,实时结果返回一些简要信息,异步结果返回详细中奖信息,供调用方后续处理。系统只保存中奖用户记录,防止大量无效抽奖记录信息挤占数据库资源。同时在抽奖过程中,每一个中断处(所有导致未中奖而退出的地方)异步记录抽奖日志,便于问题排查。可扩展性为保证良好的扩展性,上述业务对象在实现时都增加了类型字段(如图3),通过策略模式实现。如库存早期只有两种类型,后来业务需求指定日期设置库存数量,只需要增加一种按日期设置次数的库存类型,实现一个对应的子类即可,其他逻辑保持不变。图3 库存类型扩展前文介绍的大部分系统概念都是采用这种实现方式,若有新的需求接入,可增加新的实现类,然后进行重新组合,系统的扩展采用“重新组合“的方式替代原有的”逻辑调整“。最终业务中约90%的场景都可以通过配置来实现,剩下的10%也可以通过在某一个对象或者多个对象增加类型来快速支持。并发控制系统经历了两次汽车之家818百城车展、及多次大访问量业务考验,这归功于系统在并发能力上的优化。在接入层,系统对接了汽车之家API网关,对于请求进行限流,特别是直播间秒杀大额奖品的情况,瞬时流量可能达到数万QPS。这种情况下,对于非预期内的超量请求,直接返回预设中奖结果。在应用层,对性能也有较高要求。一是查询性能,需要支持在多个业务系统的展示,二是抽奖操作的性能,要做抽奖资格校验、抽奖次数校验、中奖次数校验、库存校验、中奖规则校验等。考虑到奖品配置等信息变动频率低,访问频次高,变化时要求及时生效,系统引入了支持本地缓存实时更新的基础数据组件,将奖品配置信息缓存在了应用本地缓存中,后台修改时会触发MQ广播消息,实现缓存实时更新,既保证性能,又保证及时更新。图4 并发优化奖品配置信息缓存在本地缓存中,查询性能基本得到了保证。对于抽奖操作,除了要获取奖品配置信息,还需要做抽奖基础规则校验、抽奖资格校验、抽奖次数校验、中奖次数校验、库存校验、反作弊规则校验、二次库存校验(金额类的库存,本次中奖金额+已中奖金额 通用营销抽奖系统架构设计与实践
    上一页:问界低代码平台架构设计及业务实践 下一页:车小妹规则引擎实践
    全部评论(0)