Springboot 实现红包发送和领取业务

墙外行人,墙里佳人笑。

1 前言

在前文中讲述了红包发送的算法以及对应的存储,以及红包的领取以及抢红包,在本文中将继续完善红包的内容,包括红包的发送表和领取表的设计,以及红包 24 小时超时退回的处理方式,将红包的业务构建成一个完整的闭环,形成一个真正完整的业务,分享作者在这个过程中的思考和心得。

2 红包发送

红包的发送和领取采用了策略模式,红包的发放分为个人红包和群红包两种模式。红包发送的逻辑是先计算每个红包的金额,将红包发送的数据存入数据库中,然后将红包的信息放入缓存中,缓存的 key 为红包的订单号,value 即红包的列表。

如下图群红包逻辑所示,具体实现类群红包 GroupRedPkg 中,有具体的红包算法,红包列表和红包信息的保存全部放在右侧的抽象类中,这些信息在个人红包(个人红包金额都是固定的,这里就不做展示,具体的代码可以参见项目源码)的场景下也是可以使用的,实现了相同业务的内聚。

在群红包中,计算完每个红包的金额后,需要将红包的顺序进行乱序操作 Collections.shuffle(nodeList);,这样也可以保证在领取红包时的随机性。

对于红包的发送,在计算完每个红包的金额后,需要先记录红包的发送流水,然后调用 C 端的交易接口,实际扣除用户的金额,操作完成之后,需要修改流水的状态,至此才能说红包的发送业务完成。红包的发送包含三个核心环节,红包的计算,流水的记录和修改、账户余额的扣减。

3 红包领取

红包的领取需要从缓存 redis 中获取一个红包单,判断是否超时以及是否存在,之后查询发送红包的记录,如果前置校验通过后,需要先记录红包领取人的领取记录,然后调用账户的入账接口,如果账户入账失败,需要将红包再次放入红包列表中,否则红包就丢失了。当入账成功后,需要修改入账记录为成功,然后返回结果。

领取红包,需要在红包领取入口加上分布式锁,防止红包的超额领取。

红包的领取和红包的发送时相似的,需要记录领取红包者的领取记录,用户账户增加余额,修改领取记录的状态,至此红包的领取业务完成。

4 红包退回

已经讲述了红包的发送和领取,还有一种特殊的情况,当红包超时(一般是 24h)需要将红包原路退回,或者红包剩余金额未领取超时,此种情况也需要进行退回操作。

红包退回的操作处理逻辑稍微复杂,但是是一个批量任务,可以通过定时任务触发。首先需要查询超时的红包发送记录,删除缓存中的 key, 找到可能存在的红包领取记录,计算其领取金额,红包总金额减去红包领取金额即红包需要退回的金额,如果退回金额不为零,需要操作退回,如果红包已经领取完毕,需要将红包打标,记录已经处理完毕,下次定时任务就不会处理。

5 总结

在本文中,介绍了红包的发送业务、领取业务和红包退回,实现了业务的闭环处理,对应环节的数据需要记录到数据库中,记录到数据库中后再进行账务的操作,这个记录不仅实现了业务的记录,也可以实现业务的幂等。在后续文章中,将介绍 C 端业务和 B 端的应用场景。项目 github 地址 springboot-auth

相关推荐
似水流年流不尽思念2 分钟前
MongoDB 有哪些索引?适用场景?
后端·mongodb
MacroZheng4 分钟前
横空出世!MyBatis-Plus 同款 ES ORM 框架,用起来够优雅!
java·后端·elasticsearch
武子康5 分钟前
大数据-100 Spark DStream 转换操作全面总结:map、reduceByKey 到 transform 的实战案例
大数据·后端·spark
bobz9659 分钟前
网段分配
后端
bobz96513 分钟前
VRRP 负载均衡:一个网段多个网关(网关数量和交换机数目一致:一般是两个)
后端
bobz96517 分钟前
VRRP 简记
后端
冯仙笙23 分钟前
统一支付入口集成六种支付方式
后端
无双_Joney35 分钟前
[更新迭代 - 1] Nestjs 在24年底更新了啥?(功能篇)
前端·后端·nestjs
泉城老铁43 分钟前
idea 优化卡顿
前端·后端·敏捷开发
福大大架构师每日一题1 小时前
RustDesk 1.4.2 版本发布:新增增量文件传输与光标显示功能
后端