Java 杂谈架构设计程序员之家

红包设计与实现

2018-08-15  本文已影响2人  Jay_Wei

背景

  去年年底,接到一个红包的需求:在直播间发送一个红包/用户发送大礼物,系统会生成一个大红包,让在直播间内的人抢,红包可以是金额,也可以是礼物(鲜花,鼓掌等)。用户抢到 的金额或者礼物,需要入库保存。

   先上红包随机算法实现代码,一起学习:https://download.csdn.net/download/weiwenhou/10606556

红包的设计

 1.用户发送大礼物,后台根据大礼物的金额,生成红包总金额M以及总的红包个数N

 2.尝试根据总金额M,根据要分配的个数,划分为N份。

 3.金额,红包类型,红包个数保存到DB,生成红包ID

4.把尝试划分的N份小红包放进Redis队列(leftPush all)

 5.用户请求抢红包/查看详情,如果已经抢完,过滤无效请求,放回查看详情的结果。

6.用户抢到的红包或者礼物,会异步更新到DB数据库。

流程图:

1.发红包流程图:

2.抢红包流程图:

难点

1.拆红包:

微信红包金额是拆的时候实时算出来的,采用的是纯内存计算,不需要预算空间存储;而我们的设计是预先分配好的,发完红包提前把它分配配好,生成小红包,虽然需要占存储,但是因为红包数量不会太大,并且可以减少了锁竞争,可以接通过Redis的原子操作api抢红包。

 2.红包随机分配算法

 总金额为M,分发N个红包,每个红包内的金额是0.01-(M/N*2)之前。

  比如:发10块钱红包,总共10个红包,那么抢到的每个小红包金额在0.01元~2元之前波动。

   在此附上我的分配算法代码(因为我们使用自己平台的货币,所以最小单位是0.1):

  分配算法源码地址:https://download.csdn.net/download/weiwenhou/10606556

3.高并发读

1)应对高并发,通常是业务层拦截过滤无效缓存,但考虑到直播抢红包的人数不会太大,所以暂时不拦截。

2)对DAO层增加Redis以及CaffeineCache本地缓存减少数据库压力

3)利用Redis的setnx,以及lpop的原子操作,所以不会存在一个人抢多个红包,两个人同时抢到一个红包(除非Redis挂了)

4.对账

用户每抢一个红包,都会异步记录到DB数据库,生成的红包也会记录到DB,所以可以对账红包数据是否正常。

不足

1)redis挂的话,没用通过DB保障服务继续。

总结

目前直播红包功能上线八个多月,运行良好,没发现什么异常或者数据没对上的情况。

上一篇下一篇

猜你喜欢

热点阅读