原文链接:https://www.cnblogs.com/chenyanbin/p/13587508.html
已原创授权
为啥写这个微信抢红包项目呢,公司 0202 年 08 月 22 日,公司周年庆,抢了100多红包?,O(∩_∩)O哈哈~
在 DB、Redis 分别新增一条记录
「使用技术」
Redis 中数据类型的 String 特性的原子递减(DECR key)和减少指定值(DECRBY key decrement)
「业务」
「查询红包记录」
查询 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='抢红包记
录表,抢⼀个红包插⼊⼀条记录';
发红包接口开发
❝往db中就单纯存入一条记录,Service层和Mapper层,就简单的一条sql语句,主要是提供思路,下面会附案例源码,不要慌 ❞
img
通过上图算法得出,靠前面的人,手气最佳几率小,手气最佳,往往在后面
「测试」
「发红包」
因为我发了 10 个红包,金额是 20000,使用压测工具,模拟50个请求,只允许前10个请求能抢到红包,并且金额等于20000。
布隆过滤器是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
相比于其他的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数。另外三列函数相互之间没有关系,方便由硬件并行实现。布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。
但是布隆过滤器的缺点和有点一样明显。误算率是其中之一。随着存入的元素数量增加,误算率随之增加。但是如果元素数量太少,则使用散列表足矣。
一个抽奖程序,只针对会员用户有效
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
CREATE TABLE `sys_user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(11) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '⽤户名',
`image` varchar(11) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '⽤户头像',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
dao 层和 dao 映射文件,就单纯的一个 sql 查询,看核心方法,下面会附源码滴,不要慌好嘛
「下载」
github:https://github.com/RedisBloom/RedisBloom
链接: https://pan.baidu.com/s/16DlKLm8WGFzGkoPpy8y4Aw 密码: 25w1
「编译」
make
「将 Rebloom 加载到 Redis 中」
先把 Redis 给停掉!!!在 redis.conf 里面添加一行命令->加载模块
loadmodule /usr/soft/RedisBloom-2.2.4/redisbloom.so
「测试布隆过滤器」
local bloomName = KEYS[1]
local value = KEYS[2]
--bloomFilter
local result_1 = redis.call('BF.ADD',bloomName,value)
return result_1
local bloomName = KEYS[1]
local value = KEYS[2]
--bloomFilter
local result_1 = redis.call('BF.EXISTS',bloomName,value)
return result_1
提前将秒杀数据缓存到 redis
set skuId_start_1 0_1554045087 --秒杀标识
set skuId_access_1 12000 --允许抢购数
set skuId_count_1 0 --抢购计数
set skuId_booked_1 0 --真实秒杀数
利用 Redis 缓存加速增库存数
"skuId_booked":10000 //从0开始累加,秒杀的个数只能加到1万
将用户订单数据写入 MQ(异步方式)。
另外一台服务器监听 mq,将订单信息写入到 DB。
好了,以上就是完整的开发步骤,下面我们开始编写代码
1、先判断秒杀是否已经开始
2、利用 Redis 缓存 incr 拦截流量
1、校验当前用户是否已经买过这个商品
2、校验通过直接返回抢购成功
1、库存扣除成功,获取当前最新库存
2、如果库存大于0,即马上进行库存扣除,并且访问抢购成功给用户
3、考虑原子性问题
4、返回抢购结果
set skuId_start_1 0_1554045087 --秒杀标识
set skuId_access_1 12000 --允许抢购数
set skuId_count_1 0 --抢购计数
set skuId_booked_1 0 --真实秒杀数
jmeter 配置
压测秒杀验证原子性
链接: https://pan.baidu.com/s/1hZUPRAljkqO05fYluqJBhQ 密码: 1iwr
演示的时候,我使用的 Redis 单机的,吞吐量不是很大,感兴趣的,可以自己搭建个 Redis 主从复制+哨兵+集群,然后再测试。
最近比较忙,没时间完善微信抢红包秒杀的原子性。下面那个完整案例抢库存的,亲自使用 Jmeter 压测几次,是原子性的,可以拿来借鉴,感兴趣的同学,可以借鉴下面抢库存的代码,把微信抢红包的功能在完善下,我就不修改啦。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有