使用redis队列实现抢红包
(1)1个大红包生成n份小红包,保存到数据库
(2)每个大红包对应两个redis队列,一个是未消费红包队列,另一个是已消费红包队列。开始时,把未抢的小红包全放到未消费红包队列里。
未消费红包队列里是json字符串,如{userId:'', money:'300', id:''}。
(3)判断是否领取过?
在redis中用一个map来过滤已抢到红包的用户。
抢红包时,先判断用户是否抢过红包,如果没有,则从未消费红包队列中取出一个小红包,
再push到另一个已消费队列中,最后把用户ID放入去重的map中。
(4)用一个单线程批量把已消费队列里的红包取出来,再批量update领取红包的用户ID到数据库里。
red_packet表中增加一个状态status:小红包是否存入数据库 1-已保存
问题:
什么时候更新大红包的状态?
某个用户发送红包:createSmallRedPackets(总金额, 红包数)
其他用户抢红包:grapRedPacketRedis(大红包id, 用户id)
大红包分的小红包可以放在定时任务里,这样就避免了与数据库的交互,更加节省时间
redis如何保存key-map<String,String>及对map的操作 -使用hash替代 用field字段保存用户id
public interface IRedPacketService {
/**
* 获取红包信息.
* @param id --红包id
* @return 红包具体信息
*/
public RedPacketPO getRedPacket(Integer id);
/**
* 扣减抢红包数.
* @param id -- 红包id
* @return 更新记录条数
*/
public int decreaseRedPacket(Integer id);
/**
* 抢红包
* @param redPacketId 红包id
* @param userId 用户id
* @return 影响记录数.
*/
public int grapRedPacket(Integer redPacketId, Integer userId);
/**
* 抢红包 使用存储过程
* @param redPacketId 红包id
* @param userId 用户id
* @return 影响记录数.
*/
public int grapRedPacketProc(Integer redPacketId, Integer userId);
/**
* 生成小红包并放入redis队列
* @param amount
* @param count
*/
public void createSmallRedPackets(double amount, Integer count);
/**
* 通过redis队列来抢红包
* @param redPacketId
* @param userId
* @return
*/
public int grapRedPacketRedis(Integer redPacketId, Integer userId);
/**
* 更新大红包状态 0-未保存 1-已存入数据库
* @param po
* @return
*/
int updateRedPacketStatus(RedPacketPO po);
/**
* 获取小红包未入库的大红包信息
* @return
*/
List<RedPacketPO> getRedPacketByStatus();
}
create table red_packet
(
id int(12) auto_increment COMMENT '红包编号',
user_id int(12) COMMENT '发红包的用户id',
amount decimal(16,2) COMMENT '红包金额',
send_date timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '发红包日期',
total int(12) COMMENT '红包总数',
unit_amount decimal(12) COMMENT '单个红包的金额',
stock int(12) COMMENT '红包剩余个数',
version int(12) default 0 COMMENT '版本号',
status char(1) comment '状态 0-未入库 1-已保存到数据库',
primary key(id)
);
用户抢红包表
create table red_packet_user
(
id int(12) auto_increment COMMENT '用户抢到的红包id',
red_packet_id int(12) COMMENT '大红包id',
user_id int(12) COMMENT '抢红包用户的id',
amount decimal(16,2) COMMENT '抢到的红包金额',
grab_time timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '抢红包时间',
note varchar(256) null COMMENT '备注',
primary key(id)
);
insert into red_packet(user_id, amount, send_date, total, unit_amount, stock,status)
values(1, 10000, now(), 2000, 5, 2000,'0');
分享到:
相关推荐
07-Redis队列Stream、Redis多线程详解_ev.07-Redis队列Stream、Redis多线程详解_ev.07-Redis队列Stream、Redis多线程详解_ev.07-Redis队列Stream、Redis多线程详解_ev.07-Redis队列Stream、Redis多线程详解_ev.07-...
通过redis队列实现的消息队列
Qt 使用 Redis实现 消息队列,点对点 生产者-消费者 模式
Laravel/Lumen 使用 Redis队列
php队列+php-redis队列+php-redis扩展,php入队出队,redis入队出队以及其php .dll扩展
主要为大家详细介绍了php+redis消息队列抢购实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
java使用DelayQueue延迟队列和Redis缓存实现订单自动取消功能
Thinkphp6 redis队列 消息事件 gatewayworker聊天打通版
.NET MVC Redis 实现简单的抢购队列,RPush LPop 实现高并发抢购队列
基于springboot+redis+mysql实现抢红包功能项目源码+项目说明+框架图.7z 【功能】 当前端点击抢红包按钮时,如果出现“系统繁忙”,表示抢红包失败,允许按钮再次被点击;如果出现“抢红包中”,则按钮不允许再次...
redis实战之抢红包系统.zip
整个延迟队列由4个部分组成: 1. JobPool用来存放所有Job的元信息。 2. DelayBucket是一组以时间为维度的有序队列,用来存放所有需要延迟的Job(这里只存放Job Id)。 3. Timer负责实时扫描各个Bucket,并将delay...
redis分布式锁实现抢单秒杀,模拟场景,在多用户的情况下进行秒杀抢单,实现库存的变化,一级抢单返回状态。
Laravel7中Redis队列的使用
http://127.0.0.1:8000/getList queueName">一个NodeJS和redis做的基于http协议使用的队列 做了点小修改 支持多个队列和post提交 原github地址:https://github.com/lnmp/nodemq 使用方法: 在安装好redis和nodejs...
Serve 基于Swoole Server 编写的消息队列消费系统
基于springboot+redis+mysql实现抢红包功能项目_源码
抽奖系统后台 springboot+mybatis redis队列处理高并发
redis队列弹幕