一、背景:为什么需要幂等性

在微服务、分布式架构下,网络不可靠、请求重试机制(如前端超时重发、客户端重发、网关重试、消息消费失败重试等)会带来重复请求,如果接口没有幂等性,可能导致:

  • 重复扣费
  • 重复订单
  • 重复数据写入
  • 资源状态异常

因此接口的幂等性是保障系统一致性、稳定性的关键。


二、幂等性的演进历程

阶段实现方式适用场景特点
1. 前端防重复提交禁用按钮、Token机制简单场景(如表单)限制小,易绕过
2. 数据库唯一约束唯一索引字段控制插入插入类接口利用数据库能力
3. 幂等标识(唯一业务ID)唯一业务号控制幂等订单类接口明确控制粒度
4. 分布式锁请求上锁任意接口控制请求串行,牺牲吞吐
5. 状态机机制状态+版本控制状态转换操作精细控制副作用
6. Redis 幂等性控制幂等Key+过期时间高并发下快速、安全,结合令牌机制

三、最佳实践总结

🧠 原则

  • 幂等性以“结果相同”为基准,副作用不可重复。
  • 控制粒度应适当:写操作必须幂等,读操作天然幂等。
  • 幂等 Token 最好由客户端生成或服务端下发后强制绑定。

✅ 最佳实践建议

  • 业务唯一标识驱动幂等性,如订单号、支付流水号。
  • 幂等性应放在业务代码逻辑前端处理,即“第一次判断是否重复提交”。
  • 采用 Redis + 原子操作(如SETNX)+ Token + TTL 实现防重。
  • 接口幂等性建议作为注解能力进行抽象封装,统一使用。

四、Spring Boot 实现示例(完善版)

下面我们以 Token机制 + Redis原子写入实现接口幂等性,构建完整示例。

1️⃣ 添加依赖

<!-- Redis starter -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2️⃣ Redis配置类(Lettuce连接池)

@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, String> template = new RedisTemplate<>();template.setConnectionFactory(factory);template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new StringRedisSerializer());return template;}
}

3️⃣ 幂等Token生成接口(服务端)

@RestController
@RequestMapping("/token")
public class TokenController {@Autowiredprivate RedisTemplate<String, String> redisTemplate;@GetMapping("/generate")public String generateToken() {String token = UUID.randomUUID().toString();redisTemplate.opsForValue().set("idem-token:" + token, "valid", 5, TimeUnit.MINUTES);return token;}
}

4️⃣ 幂等校验注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Idempotent {String key() default "";  // 可自定义Key策略
}

5️⃣ 幂等校验切面

@Aspect
@Component
public class IdempotentAspect {@Autowiredprivate RedisTemplate<String, String> redisTemplate;@Around("@annotation(idempotent)")public Object checkIdempotency(ProceedingJoinPoint joinPoint, Idempotent idempotent) throws Throwable {HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();String token = request.getHeader("Idempotency-Token");if (StringUtils.isEmpty(token)) {throw new RuntimeException("幂等Token不能为空");}String redisKey = "idem-token:" + token;Boolean result = redisTemplate.delete(redisKey);  // 核心逻辑:删除即消费if (Boolean.FALSE.equals(result)) {throw new RuntimeException("重复请求,请勿重复提交");}return joinPoint.proceed();}
}

6️⃣ 接口使用示例

@RestController
@RequestMapping("/order")
public class OrderController {@PostMapping("/create")@Idempotentpublic String createOrder(@RequestBody OrderDTO orderDTO) {// 模拟业务逻辑return "订单创建成功,订单号:" + UUID.randomUUID().toString();}
}

7️⃣ Postman 调用流程:

  1. 调用 GET /token/generate 获取 token

  2. 调用 POST /order/create,在请求头加上:

    Idempotency-Token: 你刚刚拿到的token
    

多次调用同一个 token,只会成功一次,后续将抛出“重复请求”异常。


五、可扩展建议

功能实现方式
支持注解中的自定义 key 逻辑SpEL 表达式,读取参数字段
幂等记录持久化Redis + 数据库双写
异常重试队列支持Kafka / RocketMQ 消息幂等处理
Redisson替换RedisTemplate使用 RLock.tryLock() 可实现锁粒度的幂等控制

六、架构图(逻辑)

客户端|
[请求附带Token]|
Spring Boot 接口(注解拦截)|
切面逻辑校验 Token|
Redis SETNX 删除 key -> 是第一次? -> 继续业务|
业务逻辑执行(订单创建、支付、提交...)

后续实例回陆续添加

参数幂等、结果缓存、幂等日志记录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90486.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90486.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/90486.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OGRE 3D----6. 背景图片渲染实现详解

1. 背景图片渲染原理 1.1 渲染队列机制 Ogre3D 使用渲染队列(Render Queue)来控制对象的渲染顺序。背景图片需要在所有其他对象之前渲染,因此我们将其设置为 RENDER_QUEUE_BACKGROUND。 1.2 视图变换控制 为了让背景图片始终保持在场景的最远处,我们需要: 使用单位投影…

K线连续涨跌统计与分析工具

K线连续涨跌统计与分析工具 1. 概述 本工具是一个用于分析金融时间序列数据(特别是K线数据)的Python脚本,主要功能是统计连续n根同方向K线后,第n+1根K线的涨跌情况。该工具不仅提供统计分析功能,还支持图形化标记以验证结果,帮助交易者和量化分析师识别市场中的特定模式…

jQuery EasyUI 简介

jQuery EasyUI 简介 引言 随着互联网技术的飞速发展,前端开发变得越来越重要。jQuery EasyUI 作为一款流行的前端UI框架,极大地简化了前端开发的工作流程,提高了开发效率。本文将详细介绍 jQuery EasyUI 的起源、特点、使用方法以及在实际项目中的应用。 一、jQuery Easy…

《测试开发:从技术角度提升测试效率与质量》

测试开发的核心工作内容与职责解析 一、测试开发的定位与核心价值 测试开发&#xff08;Test Development&#xff0c;简称 TestDev 或 SDET&#xff09;是融合软件开发能力与测试工程思维的复合型岗位&#xff0c;不同于传统测试工程师&#xff0c;其核心目标是通过技术手段提…

20250710解决KickPi的K7开发板刷机之后出现DDR异常:ch:1 dq0 fail,write:0x1,read:0x20300

20250710解决KickPi的K7开发板刷机之后出现DDR异常&#xff1a;ch:1 dq0 fail,write:0x1,read:0x20300 2025/7/10 20:36[BEGIN] 2025/7/10 19:29:03 /DDR 2f85f4b2d4 cym 25/03/04-14:38.55,fwver: v1.09 In ch0 ttot10 ch0 ttot10 ch1 ttot10 ch0 ttot18 LPDDR4, 2112MHz chan…

Ansible:强大的自动部署工具

文章目录零、Ansible介绍一、安装 ansible二、配置SSH密钥1.检查密钥是否存在2.两边的机器要互相有对方的密钥三、自动部署1.传输文件(1)inventory.ini(2)sync_blt.yml(3)执行命令2.安装软件(1)inventory.ini(2)install_efvs.yml(3)执行命令零、Ansible介绍 Ansible 是一个开源…

Nacos的基本功能以及使用Feign进行微服务间的通信

Nacos是Dynamic Naming and Configuration Service的缩写。What’s Nacos? 下面结合SpringBoot项目&#xff0c;为你介绍Nacos的基本功能以及如何使用Feign进行微服务间的通信。 一、Nacos的基本功能 Nacos是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管…

C1编译器和C2编译器Test01

在HotSpot VM中内嵌有两个JIT编译器&#xff0c;分别为Client Compiler和Server Compiler&#xff0c;通常简称为C1编译器和C2编译器。开发人员可以通过如下命令显式指定JVM在运行时到底使用哪一种即时编译器。(1)-client&#xff1a;指定JVM运行在Client模式下&#xff0c;并使…

MongoDB与Spring Boot完整使用指南

目录 1. MongoDB基础概念 什么是MongoDB? 核心概念对比 文档结构示例 2. MongoDB的特点与优势 主要特点 适用场景 3. MongoDB基本操作 基本CRUD操作 插入文档 查询文档 更新文档 删除文档 4. Spring Boot集成MongoDB 步骤1:添加依赖 步骤2:配置数据库连接 …

swift开发,关于应用、页面、视图的生命周期

目录一、应用生命周期&#xff08;App Lifecycle&#xff09;UIKit (AppDelegate)SwiftUI (使用 ScenePhase)二、页面生命周期&#xff08;ViewController Lifecycle&#xff09;三、视图生命周期&#xff08;UIView Lifecycle&#xff09;四、SwiftUI 视图生命周期五、关键对比…

借助HarmonyOS SDK,《NBA巅峰对决》实现“分钟级启动”到“秒级进场”

《NBA巅峰对决》是由望尘科技推出的国内首个真实还原5V5王朝模式的操作篮球手游&#xff0c;提供流畅操作手感和真实篮球赛场体验。丰富的玩法在为玩家带来高质游戏体验的同时&#xff0c;间接带来了启动流程冗长的问题&#xff0c;资源更新阶段的等待感尤为突出。 “我们发现&…

HT-LINK ICE:海速芯32Gbps信号调理芯片,40dB补偿+国产自主,打破高速互联瓶颈!

HT-LINK ICE&#xff08;TENX海速芯&#xff09;产品解析与推广文案一、产品定位HT-LINK ICE是TENX海速芯推出的高速信号调理芯片&#xff0c;专为PCIe 5.0/6.0、USB4、Thunderbolt等超高速接口设计&#xff0c;提供信号完整性增强和时钟恢复功能&#xff0c;适用于数据中心、A…

深入剖析 ADL:C++ 中的依赖查找机制及其编译错误案例分析

一、ADL 的定义与背景&#xff08;一&#xff09;ADL 的定义ADL&#xff08;Argument-Dependent Lookup&#xff0c;依赖查找&#xff09;是 C 中一种特殊的名称查找机制&#xff0c;用于在调用函数时&#xff0c;根据函数参数的类型来确定查找的命名空间范围。ADL 的核心思想是…

【科研绘图系列】R语言绘制相关系数图

文章目录 介绍加载R包数据下载导入数据数据预处理画图系统信息参考介绍 【科研绘图系列】R语言绘制相关系数图 加载R包 library(vegan) library(dplyr)# install.packages("./RVisulizationData/003.mantel test/ggcor_0.9.8.1.tar.gz", repos = NULL, type = &quo…

pharokka phold--快速噬菌体注释工具

pharokka是一款专用于噬菌体基因组及宏基因组的快速标准化注释工具。PS.仍在积极更新中&#xff0c;最近一次更新是在今年6.20。 若需对细菌基因组进行快速标准化注释&#xff0c;建议使用Bakta。启发pharokka开发及命名的Prokka也是优秀选择&#xff0c;但Bakta实为Prokka的卓…

深入浅出 Python Asynchronous I/O:从 asyncio 入门到实战

在现代软件开发中&#xff0c;性能是一个永恒的话题。特别是在处理网络请求、文件读写等 I/O 密集型任务时&#xff0c;传统的同步编程模型可能会因为等待而浪费大量时间。为了解决这个问题&#xff0c;异步编程应运而生。Python 通过内置的 asyncio 库&#xff0c;为开发者提供…

OpenCV颜色矩哈希算法------cv::img_hash::ColorMomentHash

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该类实现了颜色矩哈希算法&#xff08;Color Moment Hash&#xff09;&#xff0c;用于图像相似性比较。它基于图像在HSV颜色空间中的颜色矩统计特…

上海交大医学院张维拓老师赴同济医院做R语言训练营培训

当前&#xff0c;医学与人工智能的深度融合正迎来历史性发展机遇。华中科技大学同济医学院附属同济医院&#xff08;以下简称“同济医院”&#xff09;作为医疗人工智能应用的先行探索者&#xff0c;已在电子病历辅助书写、科研数据分析、医疗合同自动化审核等关键场景完成试点…

使用阿里云/腾讯云安装完成mysql使用不了

显示错误1130 - Host 106.228.110.117 is not allowed to connect to this MySQL server解决方案进入服务器的mysql命令行mysql -u root -p查看数据库SHOW DATABASES;选择mysql数据库USE mysql;查看里面的表SHOW TABLES;查询user表格的权限限制SELECT Host, User FROM user;将权…

第35周—————糖尿病预测模型优化探索

目录 目录 前言 1.检查GPU 2.查看数据 ​编辑 3.划分数据集 4.创建模型与编译训练 5.编译及训练模型 6.结果可视化 7.总结 前言 &#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客 &#x1f356; 原作者&#xff1a;K同学啊 1.检查GPU import torch.n…