群发红包系统

业务流程

发红包

  1. 输入金额以及人数
  2. 创建红包订单(订单ID,金额,份数)
  3. 调用支付系统
  4. 红包订单支付之后红包就发出去了
  5. 钱先拆好(行锁分散,加大并发)

抢红包

  1. 抢红包业务群,检测当前是否有剩余钱
  2. 没有剩余直接返回,有剩余就将请求转发到Redis里面的list(先来先服务),同时将请求发到mq启动一个延时任务(对账作用),之后有一个worker调度中心监听Redis,也就是消费队列里面的消息。
  3. 抢红包业务群会阻塞轮询worker调度中心是否抢到红包,之后返回给用户,这个过程用户看来是同步的,只是在后端用Redis的list实现了简单排下队异步。

拆红包

  1. 抢到红包之后,计算红包的金额,计算更新剩余的红包的余额。
  2. 分支1:返回给用户
  3. 分支2:将拆红包的流水写到数据库里面(MQ异步记账)
    1. 红包结算(异常结算池)
    2. 红包入账

1632562852736-31d73078-0760-4561-af09-ffd905e63c57.png

业务特点

  • 个数少,人数少:小系统
  • 个数多,人数少:美团。饿了么红包
  • 个数多,人数大:微信群红包
  • 个数少,人数多:春晚红包

设计思路

  • 数据量大:分库分表
  • 避免所有请求都到达DB:Redis
  • 并发请求量大:Redis高可用 + 分布式ID + 消息队列
  • 抢红包的FIFO保证:mq还是Redis
    • 使用mq就是过于重量级,这种消息小而且是比较多的请求,最好不使用,kafka在topic多的时候容易性能下降、
    • 使用Redis的list就可以性能比较高。
  • 响应快
  • 转账和热点数据
  • 金融系统的安全问题:账务对账
    • 1632562798735-dfbe8155-e937-456e-99de-e5c764c847dd.png

实体设计

红包表

  • 红包ID
  • 发的用户ID
  • 红包的金额
  • 红包的人头数
  • 支付的状态
  • 已抢人数
  • 版本号

拆红包流水表

  • 拆红包流水号
  • 红包ID
  • 拆红包的用户ID
  • 得到的金额
  • 时间

实现一:微型系统(100个红包,1000个人抢)

  • 一个分布式锁:同时抢,使用分布式锁排队,要求抢红包3s内返回,1个DB操作20ms(MySQL的行级锁),所以100个红包就是2000ms也就是2s抢完,满足3s之内。

  • 分表:数据量多的时候

  • 控制重复抢红包

实现二:小型系统(1000个红包,10000个人抢)

  • 预先拆分红包到数据库:钱先按照个数拆分好,就有多个行锁
  • 多个分布式锁:钱先按照个数拆分好,就有多个行锁,这个时候就使用对应个数的分布式锁,之后使用hash将锁分散到不同的锁上面
    • 注意获取到锁之后判断一下有没有抢完,抢完就直接返回了,不要继续往下执行了
  • Redis队列:钱按照个数拆分的时候流水结果放到队列里面,分布式锁抢到之后就从队列里面取出来一个更新数据库。
  • 分表

实现三:千万级(千万个红包)

  • 异步化:增加任务调度中心,异步处理(Redis的list替换mq,更加高效,数据小且多)
    • 请求到达红包服务,抢红包请求隔离阻塞在红包服务,任务异步推送到Redis的list里面,任务调度中心拿到任务之后,使用之前的分布式锁去处理
    • 可以控制系统的吞吐量

posted on 2025-10-14 23:40  chuchengzhi  阅读(3)  评论(0)    收藏  举报

导航

杭州技术博主,专注分享云计算领域实战经验、技术教程与行业洞察, 打造聚焦云计算技术的垂直博客,助力开发者快速掌握云服务核心能力。

褚成志 云计算 技术博客