生产级实战:基于Redis Lua的分布式幂等框架设计与实现
生产级实战:基于Redis Lua的分布式幂等框架设计与实现需要先看清适用场景和关键步骤,避免只记结论却忽略实际限制。
一、痛点分析:为什么你的接口不安全?
在支付、下单、账务核心链路中,我们常遇到:
用户重复提交:前端防抖失效,用户连续点击“支付”按钮。超时重试:HTTP/RPC 客户端设置了超时重试机制(如 Feign Retry)。
消息队列重复消费:Kafka 的 Rebalance 或 RocketMQ 的 ACK 超时导致消息重新投递。
分布式事务回滚重试:Seata 或 TCC 模式的 Cancel 阶段重试。
核心诉求:
唯一性:同一个请求只执行一次。原子性:判断幂等Key是否存在、记录状态必须原子操作。
高性能:不能因为幂等校验成为系统瓶颈。
高可用:支持过期清理,防止Redis无限膨胀。
二、方案选型与设计
1. 幂等Key的设计
我们采用 业务唯一标识 令牌(Token) 的方式:
Token模式(推荐):前端在调用接口前先获取Token,提交时携带,Token用后即焚。业务Key模式:order:create:{userId}:{productId}:{timestamp},适用于MQ消费。
2. 存储选型:Redis
利用 Redis 的 SETNX (Set if Not Exists) 特性。但单纯的 SETNX 无法解决 状态流转 问题(例如:请求正在处理中,还是已处理完成)。
3. 核心逻辑
我们将幂等记录分为三个状态:
0: 处理中 (Processing)1: 处理成功 (Success)
2: 处理失败 (Fail)
三、生产级代码实战
1. 定义幂等注解(AOP的核心)
通过注解实现无侵入式的幂等校验。
2. Lua脚本:保证原子性(核心)
这是整个方案的灵魂。我们使用 Lua 脚本来处理复杂的逻辑判断,避免并发下的竞态条件。
3. Redis配置与Lua脚本加载
4. AOP切面:拦截请求
5. 业务接口应用
6. 全局异常处理器
四、源码级深度剖析
Lua脚本为何能保证原子性?
Redis 是单线程执行命令的。当 Lua 脚本被调用时,Redis 会将其作为一个 整体 执行,期间不会被其他命令打断。这就解决了以下并发问题:
线程A判断Key不存在。线程B同时判断Key不存在。
线程A设置Key,线程B设置Key(导致重复执行)。
在Lua脚本中,SET NX 和后续的 GET 操作是连续的,中间不会插入其他Redis指令,因此保证了判断和设置的原子性。
状态机设计
我们的Lua脚本实现了一个简单的 状态机:
初始状态:Key不存在。迁移1:SET NX 成功 -> 0 (Processing)。
迁移2:业务成功 -> 1 (Success)。
迁移3:业务失败 -> 2 (Fail)。
迁移4:Fail状态下再次请求 -> 重置为 0 (允许重试)。
这种设计比单纯的 SETNX 更强大,因为它区分了“处理中”和“处理完成”,有效防止了 “悬挂请求”(即第一个请求很慢,第二个请求进来时第一个还没写完结果)导致的数据不一致。
五、生产环境避坑指南
Redis Key 爆炸:务必设置合理的expire 时间。对于Token模式,建议在业务完成后主动删除Key(设置 delKey=true),减少Redis内存占用。SpEL 表达式性能:虽然 SpEL 很方便,但在超高并发下(QPS > 10万),解析表达式会有微小开销。如果对性能极度敏感,可以改为在注解中直接指定参数名,通过反射获取,或者使用 ThreadLocal 传递幂等Key。
Redis 集群模式:Lua 脚本要求所有 Key 必须落在同一个 Slot 上。我们的 Key 设计是 prefix:id,只要 prefix 相同,就会路由到同一个 Slot,因此该方案天然支持 Redis Cluster。
事务一致性:如果业务方法包含数据库事务,Lua脚本的执行是在事务之外的。这意味着:Redis中标记为成功,但数据库事务回滚了。解决方案:使用 TransactionSynchronizationManager 在事务提交后再更新Redis状态,或者采用 最终一致性 方案(定时任务核对Redis与DB状态)。
Token生成策略:如果是前端获取Token,Token必须是 一次性 的。生成Token时也要利用 Redis 的原子操作。
六、总结
本文设计了一套基于 Redis Lua AOP 的通用幂等框架。
核心优势:
通用性:通过注解和SpEL表达式,适用于任何接口。安全性:Lua脚本保证了原子性,状态机设计防止了并发问题。
高性能:Redis内存操作,微秒级响应。
可维护:AOP实现无侵入,业务代码零耦合。
生产建议:
对于核心链路(如支付),建议配合 分布式锁 使用(先拿锁,再校验幂等)。定期监控 Redis 中幂等Key的数量,防止内存泄漏。
在网关层(如Spring Cloud Gateway)也可以集成类似的幂等逻辑,做第一道拦截。
本文由 摸鱼不慌 发布,转载请注明出处。
文章链接:生产级实战:基于Redis Lua的分布式幂等框架设计与实现 - 摸鱼不慌
-
08.12
GTAOL快捷药房任务如何过
-
08.12
《猎国ol》召集队友征服险境,打造材料应有尽有
-
08.12
DNF影舞者压制技能一览
-
08.12
DNF忍者压制技能一览
-
08.12
DNF死灵压制技能一览
-
08.12
DNF刺客压制技能一览
-
-
下载
- |
-
-
下载
- 《行尸走肉第一章》免安装中文汉化硬盘版下载
- 单机|436 MB
- 一款以动作冒险为主题的游戏
-
-
下载
- 《街头霸王X铁拳》免安装中文汉化硬盘版下载
- 单机|111MB
- 一款非常好玩的格斗游戏
-
-
下载
- |
-
-
下载
- 《暗黑破坏神3》免安装繁体中文正式版下载
- 单机|7630 MB
- 一款以角色扮演为主题的游戏
-
-
下载
- 《马克思佩恩3》免安装硬盘版下载
- 单机|27033 MB
- 一款以第三人称射击为主题的游戏