`

使用redis队列实现抢红包

阅读更多
使用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');


分享到:
评论

相关推荐

    redis实战之抢红包系统.zip

    Redis作为一个键值对数据库,广泛应用于缓存、消息队列、计数器等多种场景,其速度极快,非常适合处理大量并发的请求,如抢红包系统的特性。 首先,我们要理解Redis的核心概念。Redis支持多种数据结构,如字符串...

    基于springboot+redis+mysql实现抢红包功能项目源码+项目说明+框架图.7z

    基于springboot+redis+mysql实现抢红包功能项目源码+项目说明+框架图.7z 【功能】 当前端点击抢红包按钮时,如果出现“系统繁忙”,表示抢红包失败,允许按钮再次被点击;如果出现“抢红包中”,则按钮不允许再次...

    基于springboot+redis+mysql实现抢红包功能项目-源码

    该项目是使用Spring Boot、Redis和MySQL数据库来实现的抢红包功能。这个系统设计的主要目标是创建一个高效且实时的红包分配系统,适用于线上活动或社交应用。以下将详细阐述涉及的技术点及其作用。 1. **Spring ...

    详解利用redis + lua解决抢红包高并发的问题

    通过这个方案,我们可以实现高效且安全的抢红包系统。Redis 的原子操作和Lua脚本的执行保证了并发环境下数据的一致性。此外,使用单线程进行批量更新,降低了数据库的写入压力,提高了系统的整体性能。这种设计方法...

    万人群聊抢红包实战案例.pdf

    使用Seata,可以保证跨服务调用时的数据一致性和完整性,这对于实现复杂的抢红包业务逻辑是至关重要的。 在消息队列技术应用方面,保证消息的可靠投递是一个挑战。在抢红包系统中,消息队列可能用于处理异步通知、...

    攒红包抢红包源代码

    例如,使用Redis实现分布式锁来防止并发领取红包导致的重复领取问题。 4. **消息队列**:为了处理高并发下的红包发放,可以采用消息队列如RabbitMQ或Kafka。当用户点击领取红包时,请求先放入消息队列,后台服务...

    抢红包源码

    在微信、QQ等平台上,抢红包功能尤其受欢迎,而"抢红包源码"则揭示了这一功能背后的编程逻辑和技术实现。以下是对抢红包功能的核心知识点进行的详细解析。 1. **随机算法**: 抢红包的核心之一是红包金额的随机...

    Redis高并发秒杀和分布式锁技术应用及实战解析

    本课程旨在让你快速学习和掌握,基于Redis应用场景很...Redis的安装和环境搭建 高并发秒杀 Redis 实现分布式锁 Redis 实现微信群红包 Redis 实现项目实战讲解和代码演示thinkphp5 中如何使用 Redis常见的坑和问题交流

    php结合redis实现高并发下的抢购、秒杀功能的实例

    首先,使用Redis作为缓存系统,可以减少数据库的读写操作。在抢购开始时,我们可以先将商品库存信息存储到Redis中,而不是直接从数据库查询。Redis支持原子操作,如`INCRBY`命令,可以用来减小库存,这样在高并发...

    redis基础应用

    以及支持LUA脚本,类似数据库存储过程,用于实现更复杂逻辑,通常在秒杀、抢红包等高并发场景中使用。 然而,使用Redis时需注意内存管理。因为Redis是单线程模型,执行耗时操作(如bgsave)时会阻塞主线程,所以...

    RedPacket:QQ,微信抢红包原始码(允许学习交流使用,禁止使用商业目的)

    【RedPacket】是一个开源项目,主要涉及QQ和微信的抢红包功能的原始代码。这个项目为开发者提供了一个学习和交流的平台,让大家可以深入了解红包功能的实现机制,但明确禁止将其用于商业目的。通过分析这个项目的源...

    大促抗住零点洪峰-缓存架构体系课件

    3. **快速存取**:在高并发场景下,如秒杀、抢红包等活动,使用缓存可以极大提升数据的读写速度。 4. **防止超卖和重复抢单**:通过合理设计缓存策略,可以有效避免因并发导致的商品超卖或用户重复下单等问题。 综...

    一线互联网企业面试题.pdf

    9. 抢红包实现:可以通过原子操作和分布式锁来实现抢红包功能,确保红包金额分配的公平性。 10. Java内存模型与垃圾回收机制:Java内存模型定义了共享变量的访问规则,垃圾回收机制负责回收不再使用的对象占用的...

    阿里巴巴,天猫,支付宝面试题

    8. 一万个人抢100个红包,如何实现(不用队列),如何保证2个人不能抢到同一个红包,可用分布式锁 9. java内存模型,垃圾回收机制,不可达算法 10. 两个Integer的引用对象传给一个swap方法在方法内部交换引用,返回...

    经历BAT面试后总结的【高级Java后台开发面试指南】,纯净干货无废话,针对高频面试点

    系统设计-高并发抢红包 系统设计-答题套路 系统设计-在AWS上扩展到数百万用户的系统 系统设计-从面试者角度设计一个系统设计题 智力题 概率p输出1,概率1-p输出0,等概率输出0和1 判断点是否在多边形内部

    基础架构+宁克凡+目睹直播下载版终稿.pdf

    - 高并发红包逻辑的实现,通过设置红包初始值,减一进入红包发放逻辑,同时抢一个,且设定同时抢的人数上限。 - 云缓存的扩容问题,热点key吞吐量受限于单点,使用proxy缓存式热点key解决方案,但存在一致性问题。...

Global site tag (gtag.js) - Google Analytics