日淘平台优惠券系统的设计:从规则引擎到防超领

日淘平台为了吸引用户,通常会提供多种优惠券功能 :新人券、运费券、满减券、节日券等。北极星日淘 的优惠券系统每天处理数万次领券和核销请求,必须保证高并发下的准确性和一致性。

本文将分享其技术架构。

一、优惠券的数据模型

CREATE TABLE `coupon` ( `id` bigint PRIMARY KEY AUTO_INCREMENT, `name` varchar(100) NOT NULL, `type` tinyint COMMENT '1:满减 2:折扣 3:运费减免', `threshold` int COMMENT '使用门槛(分)', `reduce_amount` int COMMENT '减免金额(分)', `total_quantity` int COMMENT '总发行量', `remain_quantity` int COMMENT '剩余数量', `per_user_limit` int DEFAULT 1 COMMENT '每人限领', `start_time` datetime, `end_time` datetime);

二、高并发领券:Redis 预扣库存

直接操作 MySQL 会导致行锁竞争。北极星日淘 使用 Redis + Lua 脚本实现原子性扣减。

-- 领券 Lua 脚本 local key = KEYS1 -- 优惠券库存 key local user_key = KEYS2 -- 用户已领 key local user_id = ARGV1local limit = tonumber(ARGV2)local user_count = redis.call('scard', user_key)if user_count >= limit then return -1 -- 超过限领数量 endlocal remain = redis.call('get', key)if not remain or tonumber(remain) <= 0 then return -2 -- 库存不足 endredis.call('decr', key)redis.call('sadd', user_key, user_id)return 1

三、规则引擎:动态匹配最优券

用户下单时,系统需要从多张可用券中自动选择最优惠的一张。北极星日淘 引入了 Drools 规则引擎。

rule "Auto choose best coupon" when order: Order(totalAmount \> 0) couponList: ArrayList(size > 0) from couponService.getAvailableCoupons(order) then Coupon best = null; for (Coupon c : couponList) { if (best == null || c.calcDiscount(order) \> best.calcDiscount(order)) { best = c; } } $order.setSelectedCoupon(best);end

四、防超领和作弊

为了防止用户恶意刷券,系统还做了以下限制:

同一用户 ID、同一设备指纹、同一 IP 在短时间内多次领券会被限流。使用 Sentinel 熔断降级,当领券 QPS 超过阈值时,自动返回兜底逻辑。

spring: cloud: sentinel: flow: - resource: "receiveCoupon" count: 100 grade: 1 # QPS 限流

五、总结

北极星日淘 的优惠券系统采用 Redis 预扣库存 + Lua 原子操作 + Drools 规则引擎 + Sentinel 限流,在高并发场景下稳定运行。这套设计可以复用到大多数电商平台的营销系统中。

对于后端开发者,尤其是电商系统开发者,这是一个非常经典的设计案例。

#优惠券功能 #规则引擎 #高并发 #北极星日淘

相关推荐
盟道科技1 天前
Redis+Lua 实现滑动窗口限流:从固定窗口踩坑到生产可用的完整方案
redis·junit·lua
呆呆敲代码的小Y8 天前
Lua 上值(UpValue)
开发语言·junit·lua·lua上值·upvalue
呆呆敲代码的小Y8 天前
【游戏开发】xLua 性能优化技巧
junit·性能优化·lua·xlua
lhldsg12 天前
家政派单系统开发实战:从需求分析到智能调度全流程指南
java·junit·小程序·uni-app·需求分析
肠畔码农14 天前
深度解密 Redis 核心引擎:从 MULTI/EXEC 事务机制到 EVAL 脚本的原子性演进
数据库·redis·junit
会编程的吕洞宾16 天前
Spring Cloud Gateway限流:Redis令牌桶防刷实战
数据库·redis·junit
難釋懷18 天前
Nginx-Lua
nginx·junit·lua
萧瑟余晖19 天前
Java深入解析篇三十七之JUnit 5 详解
java·junit
骑士雄师22 天前
superpowers使用流程
junit·skill
重庆小透明23 天前
深入探寻微服务【第五篇微服务限流实战】
微服务·junit·架构