抽奖系统
抽奖系统
高QPS系统需要有什么
总结一个高QPS的业务,要做好:
- 高qps服务承载:redis
- 防止打爆下游服务可以使用削峰填谷的消息队列:kafka
- 流量打入后要漏斗化:越接近底层的服务流量需要越少
- 要有熔断机制:直接返回未中奖
- 要有灾备机制:DB+log
抽奖业务
中奖逻辑:
获得抽奖机会>>扣减抽奖机会>>概率计算是否可以中奖>>是否已经中过奖>>中奖>>结束
抽奖系统:
抽奖次数:有优先级,优先扣除顺序a-b-c
每日有一次机会,不叠加
奖品有再抽一次
商品交易会增加抽奖次数
奖品:
大量的虚拟奖品(价值低)
少量的实体奖品(价值高):只有消费满一定资格,才有机会抽到
业务特点:
- QPS很高,流量漏斗化越靠近底层,流量越少
- 不能超发,会直接带来经济损失
- 防刷,防止机器人或专业团队薅羊毛
- 灾备
系统设计
- 与现有业务分离,防止抽奖影响到既有业务
- 逐层淘汰不合规请求
- 是否有中此奖品的权限:
- 奖品是本交易免单,那么前提就是进行过交易
- 奖品是实体,要求消费金额>300元
- 奖品数量:防止超发
- 是否有中此奖品的权限:
- redis:保证提供高qps服务
- 存储结构为Hash:
Map<String, Map<String, Object>>
- 分布式锁:
setnx
,防止刷奖 - 存储抽奖次数信息:
Key : Value
- 每日一次抽奖:
last_timestamp:timestamp
- 再来一次奖励:
one_more_time : cnt
- 交易抽奖次数:
transaction_time : cnt
- 每日一次抽奖:
- kafka:发奖,削峰填谷
- 存储结构为Hash:
抽奖概率模型
有几种概率模型:
概率实现确定:画一个数轴,随机数落入哪里,就中什么奖品
- 实现简单方便,但是大奖可能会早早被抽走
不要求奖品一定要送完:
抽奖概率可以随时间升高
可以设置在某个时间后一定中奖
发奖和中奖记录
抽奖的奖品可能依赖的下游服务:
- 优惠券服务
- 邮寄服务
- vip服务
抽奖的qps很高,为了不打垮下游服务,因此需要kafka做一个缓存,在中奖之后,写入kafka,再由下游慢慢消费。
中奖记录:kafka+DB+log来存储中奖记录信息。
兜底策略
- 如果redis被打爆,那么直接返回未中奖
- 中奖结果除了写入kafka、DB,还写入log,做最后兜底
- 在关键点加报警
- 做好补发奖品的脚本:查log日志,给中奖用户补发奖品