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

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

本文将分享其技术架构。

一、优惠券的数据模型

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 限流,在高并发场景下稳定运行。这套设计可以复用到大多数电商平台的营销系统中。

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

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

相关推荐
流星白龙11 小时前
【Redis】2.Redis重大版本
数据库·redis·junit
测试修炼手册2 天前
[测试技术] TestNG 入门与实战:分组、数据驱动与并行执行
junit·单元测试·log4j
START_GAME2 天前
LuaTools的使用指南
junit
测试修炼手册3 天前
[测试技术] JUnit 6 入门与实战:断言、参数化与 Mockito
数据库·junit·sqlserver
大黄说说7 天前
Hyperf 协程 PHP 实战:高并发秒杀接口从 0 到 1 落地
junit
名字还没想好☜10 天前
用 Redis + Redisson 实现分布式锁:从踩坑到生产可用
java·redis·分布式·junit·分布式锁·redisson
ipad协议源码10 天前
为何网站会出现的挂马?
junit·软件开发·开源源码
再玩一会儿看代码11 天前
JUnit 测试框架详解:从实际开发、业务测试到 Java 面试高频问题
java·经验分享·笔记·junit·面试
童话的守望者12 天前
BookHub (RWCTF 2018) 通关
junit
techdashen15 天前
Uber 如何完成超大规模 JUnit 迁移:从 JUnit 4 到 JUnit 5 的自动化工程实践
junit·sqlserver·自动化