美文网首页
Redis和微信红包实现

Redis和微信红包实现

作者: 日落_3d9f | 来源:发表于2021-11-06 11:58 被阅读0次

微信红包原理业务探讨

简介:微信红包业务探讨分析

  • 技术不只有面试,redis到底有什么实战应用

    • 面试只是表达自己的知识,而开发实战才是show time
  • 小D课堂带你进入软件开发流程剖析,图解分析流程

项目开发流程
  • 如果上司给一个任务,让我们在实现微信抢红包这个功能,我们该怎么做?

    • 业务思考,实现方式千百种,不追求方法复制,只追求推导过程的思考总结

    • 功能点探索

      • 新建红包:在DB、cache各新增一条记录

      • 抢红包:请求访问cache,剩余红包个数大于0则可拆开红包

      • key:1,value:20 string decr原子减,每次减1 , 而decreby减指定数量2

      • 拆红包: 20个红包里面有500块,key:1,value:50000(以分为单位) decreby 548,decreby 1055 ,decreby 2329

        • 请求访问cache,剩余红包个数大于0则继续,同时获取可抢红包数与金额
        • 计算金额(从1分到剩余平均值2倍之间随机数,如果不是最后一个红包,剩余金额预留最少1分给cas更新失败,最后一位拿红包的人)
        • cas更新数据库(更新红包计数表记录【剩余红包个数、剩余红包金额】、插入领取记录)
      • 查看红包记录:用户进来直接查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='抢红包记录表,抢一个红包插入一条记录';
  • 开发过程中记录表信息,养成上线前梳理好上线流程的好习惯

  • 将库表导入数据库

  • 通过mybatis generator生成代码

发红包接口实现

简介:微信红包业务探讨分析

  • 发红包功能接口开发

    • 新增一条红包记录
    • 往mysql里面添加一条红包记录
    • 往redis里面添加一条红包数量记录 decr
    • 往redis里面添加一条红包金额记录 decreby
  • 抢红包功能接口开发

    • 抢红包功能属于原子减操作
    • 当大小小于0时原子减失败
  • 当红包个数为0时后面进来的用户全部抢红包失败,并不会进入拆红包环节

  • 抢红包功能扩展设计

    • 将红包ID的请求放入请求队列中,如果发现超过红包的个数,直接返回
    • 类推出token令牌和秒杀设计原理
  • 注意点

    • 抢到红包不到能拆成功
    • 2014年的红包一点开就知道金额,分两次操作,先抢到金额,然后再转账。 2015年后的红包的拆和抢是分离的,需要点两次,因此会出现抢到红包了,但点开后告知红包已经被领完的状况。进入到第一个页面不代表抢到,只表示当时红包还有。

代码:
新增红包代码,数据库里面插入一条记录,redis里面插入该红包ID对应的红包个数和金额。


新增红包 测试抢红包 redis验证

第4集 抢红包接口实现

简介:微信红包业务探讨分析

抢红包逻辑
  • 抢红包功能接口开发

    • 在抢红包这里并不能保证用户已经能领到这个红包
    • 抢红包只是做了一个判断,判断当前是否还有红包
    • 有红包则返回可以领
    • 没红包则返回不可以领
  • 拆红包功能接口开发

    • 拆红包才是用户能领导红包
    • 这时候要先减redis里面的金额和红包数量
    • 减完金额再入库

代码:


抢红包 测试抢红包

技术角度分析以后我们应该怎么抢红包?

简介:微信红包业务探讨之拆红包原理,以及以后我们应该怎么抢红包

拆红包
  • 微信红包设计算法分析

    • 玩法:微信金额是拆的时候实时算出来,不是预先分配的,采用的是纯内存计算,不需要预算空间存储

    • 分配:

      • 发100块钱,总共10个红包,那么平均值是10块钱一个,那么发出来的红包的额度在0.01元~20元之间波动
      • 当前面4个红包总共被领了30块钱时,剩下70块钱,总共6个红包,那么这7个红包的额度在:0.01~(70➗6✖️2)=23.33之间波动
      • 这样算下去,可能会超过最开始的全部金额,因此到了最后面如果不够这么算,那么会采取如下算法:保证剩余用户能拿到最低1分钱即可
    • 存储:数据库会累加已经领取的个数与金额,插入一条领取记录。入账则是后台异步操作

    • 转账:通过财付通往红包所得者账户转账,过程通过是异步操作

代码:


抢红包主要代码 测试 拆红包 测试

抢红包项目总结

简介:微信红包业务探讨之拆红包原理,以及以后我们应该怎么抢红包

  • take all操作

    • 入库转账时需要保证红包个数和红包剩余金额正确
  • 高并发处理:红包如何计算被抢完?

    • cache会抵抗无效请求,将无效的请求过滤掉,实际进入到后台的量不大。cache记录红包个数,原子操作进行个数递减,到0表示被抢光
  • 性能扩展

    • 多主sharding,水平扩展机器
    • 数据库层面sharding分片
    • redis层面sharding分片技术
  • 业务能动性,从发展的角度来看待业务

  • 观察总结,技术赋能业务

相关文章

网友评论

      本文标题:Redis和微信红包实现

      本文链接:https://www.haomeiwen.com/subject/pkodzltx.html