秒杀场景发放优惠券,要求不能超卖怎么设计?

提问者:帅平 问题分类:面试刷题
你现在要发放一批优惠券,券库存有 1000 张,现在很多用户要来领,每人每天限领两张,这个系统如何设计?
3 个回答
对的时间对的人
对的时间对的人
这里主要考虑的问题是:
1、库存防超卖:1000张券要精确扣减,不能发超
2、限领控制:每个用户每天最多领2张
3、高并发抢券:大量用户同时抢券,系统不能崩
针对上诉的技术方案有:
1、库存扣减使用redis的lua脚本保证原子性,例如:
- Lua脚本保证原子性 
if redis.call('GET',  'coupon_stock') >= '1' then 
    if redis.call('HGET',  'user_limit:'..user_id, today) < 2 then 
        redis.call('DECR',  'coupon_stock')
        redis.call('HINCRBY',  'user_limit:'..user_id, today, 1)
        return 'SUCCESS'
    end 
end 
return 'FAILED'
2、双重校验兜底
1、前端点击后先查用户当天已领次数
2、后端操作前再查一次,防止绕过前端
发布于:3天前 IP属地:
繁星点点べ夜未央
繁星点点べ夜未央
这里还需要注意以下2个问题:
1、库存超发补偿
每天凌晨跑对账脚本,对比Redis库存和DB发放记录,如果发现超发的话,优先从未使用的券里回收,实在不行发短信补偿其他优惠
2、redis挂了切降级方案
1、快速切换本地缓存+数据库行锁方案
2、提示用户"活动太火爆,稍后再试"
发布于:3天前 IP属地:
习惯所有的虚假
习惯所有的虚假
3、异步落库
用消息队列把发放记录异步写入MySQL,防止数据库被打垮,流程是:用户领券 -> Redis操作 -> 发MQ -> 消费者写DB
这里需要注意下,如果写db失败的话,需要进行mq重试
发布于:3天前 IP属地:
我来回答