大营销平台
- 装配抽奖策略
 表:策略表strategy 策略对应奖品表strategy_award
 获取最小的奖品概率值,所有奖品的概率值之和
 用概率值之和除以最小的奖品概率值,获取范围
 范围乘以概率值,放在list集合当中
  
 打乱后放进map当中,并存储在redis里。map类型
亮点:空间换时间
-  策略权重概率装配 
 上一节是把所有策略下的奖品都装配到redis的map中去了
 这一节要把权重相关的奖品装配到redis不同的map中去
 查询策略规则表strategy_rule,获取不同权重对应的商品有哪些,然后按照上一节的方式放到redis的map中
-  抽奖前置规则过滤 
 模板模式
 参数校验->策略查询->抽奖前置规则过滤(抽象)->默认抽奖流程
 策略查询:查询strategy表,看看策略有哪些前置规则
工厂模式
 存放前置规则过滤实现
 
 策略模式
 前置规则:黑名单、权重不同实现
 黑名单:查询strategy_rule表,看看哪些用户是黑名单
 权重:查询strategy_rule表,获取积分分层,判断用户积分是否在积分分层里

- 抽奖中置规则过滤
这节的目的是添加抽奖中的规则:校验抽着的奖品是否符合规则,比如必须参加六次抽奖,这个奖品才能拿走,如果没到,就走兜底奖品
 继续上节默认抽奖流程后添加:
 
 查询奖品规则:查询strategy_award表,看中了的奖品有什么规则
 抽奖中规则过滤:查询strategy_rule表,看看这个奖品要抽几次奖才能拿走,然后判断用户抽奖次数是否符合

- 责任链模式处理抽奖规则
 这节的目的,是把之前章节中的黑名单规则、权重规则、默认抽奖流程放在一个责任链里,
 这些策略规则是一种互斥行为,比如走了黑名单规则,就不应该在继续走权重规则了。那么对于这样的情况,责任链的设计就更加合适了
  
 责任链模式实现:
 装配接口:
  
 责任链接口:
  
 抽象类:
  
 工厂构建责任链:
 利用spring自动装配,构建map
   
 查询strategy表,看看规则的顺序,根据顺序构建责任链
  
- 抽奖规则树模型结构设计
 这节的目的是,利用组合模式的规则树优化抽奖中和抽奖后的规则
 上一节的规则前规则优化,由于规则都是互斥的,所以可以用责任链模式,这一节不是简单的规则互斥,用规则树优化更为合适
  
 规则树的实现,跟责任链其实原理上是差不多的,都是先用封装节点先建立一个规则树(责任链就是一个链条),然后按照规则树节点的名称,取具体实现类进行规则过滤
 先构建规则树:
  
 然后根据构建出来的规则树节点,进行规则过滤,根据规则节点名称,获取过滤实现类
  
- 模板模式串联抽奖规则
 这节的目的是,将构建规则节点改成通过数据库来构建,并把规则树融入到抽奖模板中去
  
- 不超卖库存规则实现
 这节的目的是,库存的扣减,并且实现不超卖
  
 redis进行扣减操作,并且有兜底操作,对于每个库存setNx一个,这个是防止这种情况:
 比如现在库存扣减都是redis里实现的,会和数据库有短暂的数据不一致,比如现在redis库存是90,数据库库存是100,这时候,运营人员操作了一下,导致恢复了redis库存,恢复为了100个,这就会导致本已经卖出去的100,99,98…又卖一遍,所以加了这层兜底
redis扣减库存后,立即返回客户端,抽奖成功
采用定时任务,每5秒钟消费一次队列,来同步数据库库存
 
 往redis的队列中放奖品id
 
 定时任务取,然后更新数据库库存
-  抽奖API接口实现 
 这节主要是在trigger层添加了供前端调用的三个接口
  
-  抽奖活动订单流程设计 
 这节的目的是,开始活动领域的设计,新建了三个表
  
 抽奖活动表:raffle_activity
 参与次数表:raffle_activity_count
 活动SKU表:raffle_activity_sku
-  抽奖活动流水入库 
 这节的目的是,创建用户的下单记录,更新用户抽奖次数 ,这两个都是分库分表的
  
用户下单记录表:raffle_activity_order
 用户抽奖次数表:raffle_activity_account
 流程:
 请求参数:
 
 查询那三个配置表,获取可以参与的活动次数
 活动规则校验
 构建用户订单对象
 新建订单,并更新用户抽奖次数(放在一个事务里)
 
 亮点:请求参数里有业务唯一编号,可以防止重复插入用户下单记录表,保证不给用户重复加次数
 
-  引入MQ处理活动SKU库存一致性 
 这节的目的是完成上一节的活动动作规则校验,包括活动日期的校验,sku库存的扣减,通过责任链模式实现的
 重点是sku库存的校验和减库存操作
 同之前策略一样,扣减成功后,发送到redis的队列当中,定时任务取来更新数据库库存
  
 库存的扣减也是,redis来扣减,并且有兜底策略,多了一个如果库存没了,发送mq消息
  
 mq消费,如果redis库存是0了,就直接更新数据库吧,把之前redis队列也清空了
  
-  领取活动扣减账户额度 
 这节的目的是,用户参加活动。
 查询活动->校验活动->账户过滤->构建订单
  
 账户过滤:
 查询总账户额度:raffle_activity_account
 查询月账户额度:raffle_activity_account_month
 查询日账户额度:raffle_activity_account_day
 记录:更新这三个账户额度,都次数-1;创建参加活动记录订单:user_raffle_order 这几个都放在一个事务里
-  写入中奖记录和任务补偿发送MQ 
 这节的目的是中奖记录维护一张表里,并且把中奖信息通过mq发送出去
 中奖记录表:user_award_record
 mq重试任务表:task
 中奖记录添加和task表插入消息放在一个事务里
  
 发送消息后,更新任务状态
  
 定时任务扫描task表,重试发送失败的任务,还有初始化的任务
  
  
 task消息中有uuid防止重复消费
