导读

  前二天了一篇,Redis高级项目实战(点我直达),SpringBoot整合Redis附源码(点我直达),今天我们来一下Redis秒杀系统的设计。当然啦,Redis基础知识还不过关的先去加强下自身内功,然后在回来看这篇,Redis基础知识(点我直达)。为啥写这个微信抢红包项目呢,公司0202年08月22日,公司周年庆,抢了100多红包🧧,O(∩_∩)O哈哈~

Redis秒杀系统架构设计-微信抢红包-LMLPHP

微信抢红包实现原理

业务流程分析

 

功能拆解

新建红包

  在DBRedis分别新增一条记录

抢红包(并发)

  请求Redis红包剩余个数大于0才可以等会0时,提示用户,红包已抢完

拆红包(并发)

用到技术

  Redis中数据类型的String特性原子递减DECR key减少指定值DECRBY key decrement

业务

  1. 请求Redis,当剩余红包个数大于0红包个数原子递减,随机获取红包
  2. 计算金额,当最后一个红包时,最后一个红包金额=总金额-总已抢红包金额
  3. 更新数据库

查看红包记录

  查询DB即可

数据库表设计

红包流水表

CREATE TABLE `red_packet_info` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `red_packet_id` bigint(11) NOT NULL DEFAULT 0 COMMENT '红包id,采⽤
timestamp+5位随机数',
 `total_amount` int(11) NOT NULL DEFAULT 0 COMMENT '红包总⾦额,单位分',
 `total_packet` int(11) NOT NULL DEFAULT 0 COMMENT '红包总个数',
 `remaining_amount` int(11) NOT NULL DEFAULT 0 COMMENT '剩余红包⾦额,单位
分',
 `remaining_packet` int(11) NOT NULL DEFAULT 0 COMMENT '剩余红包个数',
 `uid` int(20) NOT NULL DEFAULT 0 COMMENT '新建红包⽤户的⽤户标识',
 `create_time` timestamp COMMENT '创建时间',
 `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP COMMENT '更新时间',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='红包信息
表,新建⼀个红包插⼊⼀条记录';

红包记录表

CREATE TABLE `red_packet_record` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `amount` int(11) NOT NULL DEFAULT '0' COMMENT '抢到红包的⾦额',
 `nick_name` varchar(32) NOT NULL DEFAULT '0' COMMENT '抢到红包的⽤户的⽤户
名',
 `img_url` varchar(255) NOT NULL DEFAULT '0' COMMENT '抢到红包的⽤户的头像',
 `uid` int(20) NOT NULL DEFAULT '0' COMMENT '抢到红包⽤户的⽤户标识',
 `red_packet_id` bigint(11) NOT NULL DEFAULT '0' COMMENT '红包id,采⽤
timestamp+5位随机数',
 `create_time` timestamp COMMENT '创建时间',
 `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP COMMENT '更新时间',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='抢红包记
录表,抢⼀个红包插⼊⼀条记录';

Redis秒杀系统架构设计-微信抢红包-LMLPHP

Redis秒杀系统架构设计-微信抢红包-LMLPHP

发红包API

发红包接口开发

  • 新增一条红包记录
  • 往mysql里面添加一条红包记录
  • 往redis里面添加一条红包数量记录
  • 往redis里面添加一条红包金额记录

Redis秒杀系统架构设计-微信抢红包-LMLPHP

  注意,往db中就单纯存入一条记录,Service层和Mapper层,就简单的一条sql语句,主要是提供思路,下面会附案例源码,不要慌

抢红包API

  • 抢红包功能属于原子减操作
  • 当大小小于0时原子减失败
  • 红包个数为0时,进来的用户全部抢红包失败,并不会进入拆红包环节
  • 抢红包功能设计
    • 将红包ID的请求放入请求队列中,如果发现超过红包的个数,直接返回
  • 注意事项
    • 抢到红包不一定能拆成功

 抢红包算法拆解

Redis秒杀系统架构设计-微信抢红包-LMLPHP

  通过上图算法得出靠前面的人,手气最佳几率小手气最佳,往往在后面

  1. 发100元,共10个红包,那么平均值是10元一个,那么发出来的红包金额在0.01~20元之间波动
  2. 当前面4个红包总共被领了30元时,剩下70元,总共6个红包,那么这6个红包的金额在0.01~23.3元之间波动

抢红包接口开发

Redis秒杀系统架构设计-微信抢红包-LMLPHP

测试

发红包

Redis秒杀系统架构设计-微信抢红包-LMLPHP

模拟高并发抢红包(Jmeter压测工具)

  因为我发了10个红包金额是20000,使用压测工具,模拟50个请求只允许前10个请求能抢到红包并且金额等于20000

Redis秒杀系统架构设计-微信抢红包-LMLPHP

Redis秒杀系统架构设计-微信抢红包-LMLPHP

Redis秒杀系统架构设计-微信抢红包-LMLPHP

项目源码下载

链接: https://pan.baidu.com/s/1knmVMKBldVe46cmXqqfGpw  密码: a7o7

未完待续

  微信上有个小伙伴刚好要做一个秒杀的系统,催我赶紧把博客更新出来。过2天继续往下更新,布隆过滤器。

08-26 13:10