当前位置: 首页 > article >正文

Redis 实现接口幂等性的三种高效策略

1. 接口幂等性基础认知第一次听说幂等性这个词时我正盯着生产环境里两条完全相同的订单记录发愁。用户只是抱怨页面卡顿多点了两次提交按钮结果系统就产生了重复数据。这种场景就像你去ATM机取钱输入密码后机器没反应于是你又按了一次——如果银行系统没有幂等性控制你的账户可能就被扣了两次款。幂等性的数学本质其实很简单f(x) f(f(x))。翻译成程序员能理解的话就是无论调用多少次结果都和调用一次相同。在HTTP协议中GET、PUT、DELETE都是幂等的而POST是非幂等的。这就像你刷新网页(GET)不会改变内容但重复提交表单(POST)就可能产生多条数据。在实际业务中这些场景最容易出现幂等问题支付系统网络超时导致重复扣款订单创建用户快速点击生成多个订单库存扣减并发请求导致超卖消息队列消费者重试造成重复处理我曾遇到过最棘手的案例是医院挂号系统某个专家号被重复预约了三次。排查发现是移动端在网络抖动时自动重试导致的。这就是为什么我们需要Redis这样的利器——它不仅能解决幂等问题还能保持系统的高性能。2. Token机制先领票再办事去年给电商系统做秒杀功能时Token机制帮了大忙。它的原理就像银行排队先取号(Token)等叫到号才能办理业务。具体实现分为五个步骤客户端调用/getToken接口获取令牌服务端生成UUID作为Token存入Redis并设置过期时间客户端提交业务请求时携带该Token服务端校验Redis中是否存在该Token存在则删除Token并处理业务不存在则拒绝请求这里有个关键细节检查Token和删除Token必须是原子操作。我早期版本用两步操作就踩了坑// 错误示范非原子操作可能重复处理 if(redisTemplate.hasKey(token)) { redisTemplate.delete(token); processRequest(); }后来改用Lua脚本保证原子性-- KEYS[1]是token键名 if redis.call(GET, KEYS[1]) then redis.call(DEL, KEYS[1]) return true end return false在SpringBoot中的完整实现RestController public class TokenController { Autowired private StringRedisTemplate redisTemplate; GetMapping(/token) public String getToken() { String token UUID.randomUUID().toString(); redisTemplate.opsForValue().set( token, 1, 5, TimeUnit.MINUTES); // 5分钟过期 return token; } PostMapping(/submit) public ResponseEntityString submit( RequestHeader(X-Token) String token) { String script if redis.call(GET, KEYS[1]) then redis.call(DEL, KEYS[1]) return true end return false; Boolean result redisTemplate.execute( new DefaultRedisScript(script, Boolean.class), Collections.singletonList(token)); if(Boolean.TRUE.equals(result)) { // 处理业务逻辑 return ResponseEntity.ok(成功); } return ResponseEntity.badRequest().body(请勿重复提交); } }实际踩坑经验Token过期时间要根据业务合理设置支付类建议5分钟前端需要实现Token自动获取和重试机制在高并发场景下Redis可能需要分片部署3. 唯一序列号给每个请求办身份证物流系统的运单号给了我灵感——为什么不用唯一ID来标识每个请求呢这种方案特别适合第三方系统对接调用方生成唯一请求ID如订单号调用接口时携带该ID服务端将ID作为Redis Key存入重复请求会被Redis拦截public boolean checkRequestId(String requestId) { // SETNX EXPIRE 原子操作 Boolean result redisTemplate.opsForValue().setIfAbsent( req: requestId, 1, 10, TimeUnit.MINUTES); return Boolean.TRUE.equals(result); }性能优化技巧对RequestId做MD5压缩减少存储空间使用Redis集群提高吞吐量针对热点请求可以采用本地缓存Redis二级校验在物流轨迹更新系统中我们结合了唯一序列号和版本号UPDATE package_tracking SET status DELIVERED, version version 1 WHERE package_id ? AND version ?这样即使重复请求数据库层面的乐观锁也能兜底。4. 分布式锁业务处理的VIP通道大促时库存系统的惨痛教训让我意识到有些业务需要强一致性保障。Redis分布式锁就是解决方案public String deductStock(String productId) { String lockKey lock:stock: productId; String clientId UUID.randomUUID().toString(); try { // 尝试获取锁 Boolean locked redisTemplate.opsForValue() .setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS); if(Boolean.TRUE.equals(locked)) { // 处理核心业务 return 扣减成功; } return 系统繁忙请重试; } finally { // 确保只释放自己的锁 String script if redis.call(GET, KEYS[1]) ARGV[1] then return redis.call(DEL, KEYS[1]) else return 0 end; redisTemplate.execute( new DefaultRedisScript(script, Long.class), Collections.singletonList(lockKey), clientId); } }关键注意事项必须设置锁的过期时间防止死锁每个客户端使用唯一标识避免误删他人锁考虑锁续期问题复杂场景可用Redisson锁粒度要尽可能细如按商品ID加锁在秒杀系统中我们最终采用了分段锁方案将100个商品库存分成10组用10个锁来减少竞争。配合Redis集群QPS从最初的200提升到了5000。5. 方案选型指南面对具体业务场景时我的选择策略是这样的方案适用场景性能影响实现复杂度可靠性Token机制用户交互类操作表单提交中低高唯一序列号第三方系统对接低中中分布式锁资金/库存等强一致性场景高高高最近在物联网项目中我们还创新性地组合使用了这些方案先用Token防表单重复提交再用分布式锁保证设备状态变更的原子性。Redis的多种数据结构为幂等控制提供了灵活的选择比如String存储Token/序列号Set快速查找是否存在Hash存储复杂校验信息记得在方案落地时一定要加上详细的日志和监控。我们曾经用PrometheusGranfa搭建了幂等拦截看板能实时发现异常重复请求。这些数据对后续的性能调优和容量规划也很有帮助。

相关文章:

Redis 实现接口幂等性的三种高效策略

1. 接口幂等性基础认知 第一次听说"幂等性"这个词时,我正盯着生产环境里两条完全相同的订单记录发愁。用户只是抱怨页面卡顿多点了两次提交按钮,结果系统就产生了重复数据。这种场景就像你去ATM机取钱,输入密码后机器没反应&#…...

投资成本(容量相关)

基于多目标粒子群算法的储能容量配置 基于IEEE33节点电网,多目标 分布式电源,配网规划 基于多目标粒子群算法的储能容量配置 基于IEEE33节点电网,建立以储能投资成本 网损成本 峰谷套利收益为成本目标,以电压最小最小为安全指标的…...

[Refactor]CPP Learn Data Day 信

一、什么是urllib3? urllib3 是一个用于处理 HTTP 请求和连接池的强大、用户友好的 Python 库。 它可以帮助你: 发送各种 HTTP 请求(GET, POST, PUT, DELETE等)。 管理连接池,提高网络请求效率。 处理重试和重定向。 支…...

ESP-IDF项目中的CMakeLists.txt配置:如何高效管理.c和.h文件

1. 为什么需要高效管理.c和.h文件 在ESP-IDF项目中,随着功能模块不断增加,代码文件会越来越多。想象一下,如果你的项目里有几十个.c文件和对应的.h文件,每次新增或修改文件都要手动调整编译配置,那简直是场噩梦。我刚开…...

PX4无人机调参实战:从滤波到PID的飞行优化指南

1. 从振动分析到滤波调参:PX4飞控的降噪基础 刚接触PX4飞控调参的新手常会遇到这样的场景:无人机起飞后出现高频抖动,电机异常发热,甚至出现不受控的随机偏转。这些问题往往源于一个共同敌人——振动噪声。去年调试一架轴距650mm的…...

台达PLC伺服追剪程序及电子凸轮技术,含DVP15MC源代码与触摸屏程序一体化解决方案

台达PLC伺服追剪程序,电子凸轮,全部源代码,PLC程序和触摸屏程序,DVP15MC。最近在搞台达PLC的追剪项目,发现里面电子凸轮的设计挺有意思。直接上干货,咱们先看这个追剪系统的核心逻辑——电子凸轮的参数配置…...

语言的边界,与软件的命运憾

1. 引入 在现代 AI 工程中,Hugging Face 的 tokenizers 库已成为分词器的事实标准。不过 Hugging Face 的 tokenizers 是用 Rust 来实现的,官方只提供了 python 和 node 的绑定实现。要实现与 Hugging Face tokenizers 相同的行为,最好的办法…...

交换机堆叠技术实战:从原理到配置的全面解析

1. 为什么需要交换机堆叠? 想象一下你管理着一个中型企业的网络,核心机房里有5台独立工作的交换机。每次新增设备都要手动配置每台交换机,故障时得逐台排查,升级系统更是要一台台操作——这种场景下,交换机堆叠技术就像…...

PNGenc:面向MCU的45KB轻量级PNG编码器

1. PNGenc:面向资源受限MCU的轻量级PNG编码器深度解析1.1 设计背景与工程动因PNGenc并非对标准libpng的移植或裁剪,而是在“零依赖、零堆内存、零规格妥协”原则下,从PNG规范(ISO/IEC 15948:2003)和DEFLATE压缩算法&am…...

微信与支付宝退款接口典型错误排查与实战优化策略

1. 微信支付退款接口典型错误解析 微信支付的退款功能是电商平台必备能力&#xff0c;但很多开发者在对接时都踩过"订单号非法"这个坑。去年我们团队处理过一个紧急case&#xff1a;某跨境电商平台凌晨爆发大量退款失败&#xff0c;日志里清一色的<err_code_des&g…...

从本地到云端:FastAPI服务器部署的5个必知要点(避坑指南)

从本地到云端&#xff1a;FastAPI服务器部署的5个必知要点&#xff08;避坑指南&#xff09; 当你兴奋地完成了一个FastAPI应用的开发&#xff0c;准备将它从本地环境迁移到云端服务器时&#xff0c;可能会遇到各种意想不到的问题。接口无法访问、性能突然下降、请求超时...这些…...

2026年硕士论文AI率15%以下怎么保证?实测工具推荐附操作指南

硕士论文AI率15%以下&#xff0c;这条线现在是很多学校的硬要求。比本科的30%严多了&#xff0c;但处理起来也有方法。 写这篇的起因是帮导师组里的一个师弟处理论文AI率问题。他的论文8万多字&#xff0c;知网AIGC检测给出AI率22%&#xff0c;需要降到15%以下才能送盲审。用嘎…...

LwJSON:嵌入式轻量级JSON解析器深度解析

1. LwJSON&#xff1a;面向嵌入式系统的轻量级 JSON 解析器深度解析在资源受限的嵌入式系统中&#xff0c;JSON 数据交换正从“可选能力”演变为“基础能力”。从 STM32F0 系列微控制器上的传感器配置下发&#xff0c;到 ESP32 模组与云平台的 OTA 参数同步&#xff1b;从 LoRa…...

东南亚电商支付方式有哪些?2026最新整

东南亚电商支付方式以电子钱包、信用卡支付、实时转账和国家统一二维码为核心。印尼常用GoPay、DANA、QRIS&#xff0c;泰国 以PromptPay和TrueMoney为主&#xff0c;马来西亚主流是DuitNow和TouchnGo&#xff0c;新加坡则以PayNow和GrabPay覆盖核心场景。 对于独立站卖家而言…...

SpringCloud进阶--Sentinel 流量防卫兵衅

一、项目背景与核心价值 1. 解决的核心痛点 Navicat的数据库连接密码并非明文存储&#xff0c;而是通过AES算法加密后写入.ncx格式的XML配置文件中。一旦用户忘记密码&#xff0c;常规方式只能重新配置连接&#xff0c;效率极低。本项目只作为学习研究使用&#xff0c;不做其他…...

SenseBoxBLE库详解:phyphox协议下的Arduino BLE透传实践

1. SenseBoxBLE 库深度解析&#xff1a;面向嵌入式工程师的 BLE 数据透传实践指南1.1 库定位与工程价值SenseBoxBLE 是一个专为 senseBox 生态设计的轻量级 Arduino 兼容 BLE 通信库&#xff0c;其核心目标并非构建通用 BLE 协议栈&#xff0c;而是实现传感器数据到 phyphox 移…...

Android10剪贴板限制下的高效适配策略与实践

1. Android10剪贴板限制的背景与影响 Android10引入的剪贴板访问限制是近年来系统安全策略升级的重要一环。简单来说&#xff0c;当你的应用处于后台时&#xff0c;系统会禁止它读取剪贴板内容。这个变化看似微小&#xff0c;却让很多依赖剪贴板监听功能的应用不得不重新思考实…...

Sourcetree实战指南:从零上手代码克隆、高效合并与冲突化解

1. 为什么你需要Sourcetree这款Git可视化工具 刚接触Git版本控制时&#xff0c;命令行操作总是让人望而生畏。记得我第一次用git merge时&#xff0c;不小心把同事的代码覆盖了&#xff0c;整个下午都在手忙脚乱地恢复文件。直到发现了Sourcetree这个神器&#xff0c;才真正体会…...

CMake变量实战:从基础引用到高级构建控制

1. CMake变量基础&#xff1a;从入门到精通 CMake变量是构建系统的核心元素&#xff0c;就像编程语言中的变量一样&#xff0c;它们可以存储和传递各种信息。我第一次接触CMake变量时&#xff0c;完全被各种前缀和命名规则搞晕了&#xff0c;直到踩过几次坑后才真正理解它们的运…...

wso~.升级到.需要更新的数据表戳

1. 架构背景与演进动力 1.1 从单体到碎片化&#xff1a;.NET 的开源征程 在.NET Framework 时代&#xff0c;构建系统主要围绕 Windows 操作系统紧密集成&#xff0c;采用传统的封闭式开发模式。然而&#xff0c;随着.NET Core 的推出&#xff0c;微软开启了彻底的开源与跨平台…...

emGUI:嵌入式轻量级Widget GUI框架解析

1. 项目概述 ESP8266 emGUI 是一款专为资源受限嵌入式平台设计的轻量级 C 语言图形用户界面&#xff08;GUI&#xff09;库&#xff0c;其核心目标并非替代成熟的 GUI 框架&#xff08;如 LVGL 或 TouchGFX&#xff09;&#xff0c;而是提供一套高度可裁剪、零依赖、可深度集成…...

个人开发者如何评估一个AI Token代理服务商的技术实力?

作为个人开发者&#xff0c;评估 AI Token 代理服务商&#xff08;API 中转平台&#xff09;的技术实力&#xff0c;核心是“把黑盒变灰盒”。不要只看价格和宣传&#xff0c;要通过可观测性、兼容性、容错机制三个维度进行实战验证。一、基础兼容性&#xff1a;接口规范与模型…...

OpenClaw模型热切换:Qwen3.5-9B-AWQ-4bit与其他模型动态调用

OpenClaw模型热切换&#xff1a;Qwen3.5-9B-AWQ-4bit与其他模型动态调用 1. 为什么需要模型热切换 去年冬天&#xff0c;我正用OpenClaw处理一批产品截图的分析任务。当时只配置了Qwen3.5-9B-AWQ-4bit这一个模型&#xff0c;结果发现——简单图片描述消耗了过多算力&#xff…...

R语言农业预测代码开源泄露?3个被90%农科院忽略的产量建模陷阱(附可复现代码)

第一章&#xff1a;R语言农业产量预测代码开源泄露事件全景剖析 2023年夏季&#xff0c;某国家级农业大数据平台在GitHub公开仓库中意外暴露了包含真实县域气象、土壤与历史产量数据的R语言建模脚本&#xff0c;引发行业级安全震动。该仓库原意为教学示范&#xff0c;但因.giti…...

(31)列出视图的垂直模式,起点在上方。水平模式,起点在左边。对于水平滚动框,也是如此

&#xff08;55&#xff09;&#xff08;56&#xff09; 谢谢...

R语言临床数据挖掘的7个致命陷阱:92%的医学研究者在第3步就失败了?

第一章&#xff1a;临床数据挖掘的医学伦理与R语言合规性基础临床数据挖掘在推动精准医疗与公共卫生决策中具有不可替代的价值&#xff0c;但其前提是严格遵循医学伦理原则与数据治理规范。世界医学会《赫尔辛基宣言》与我国《涉及人的生物医学研究伦理审查办法》均强调&#x…...

2026届毕业生推荐的十大AI学术网站横评

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek AI论文查重系统依靠深度学习跟自然语言处理技术&#xff0c;能够针对论文文本开展语义级相似…...

手搓单片机

“手搓单片机”在电子爱好者的语境里&#xff0c;通常指绕开现成的开发板&#xff0c;自己从零搭建一个“最小系统”。这就像给芯片造一个能呼吸、能思考的“身体”。对于新手&#xff0c;最经典的入门路径是51单片机&#xff08;如 STC89C52&#xff09;。下面这份手搓指南分为…...

告别手动复制粘贴!用PowerShell脚本批量下载全球1米树冠高度数据(附完整脚本)

告别手动复制粘贴&#xff01;用PowerShell脚本批量下载全球1米树冠高度数据&#xff08;附完整脚本&#xff09; 在生态研究和地理信息系统&#xff08;GIS&#xff09;工作中&#xff0c;处理大规模栅格数据是家常便饭。想象一下&#xff0c;当你需要下载数百个甚至上千个1米…...

SAP MM BAPI_PO_CHANGE 报错请输入净价,明明已经传值净价!

1、问题&#xff1a;明明已经传入净价&#xff0c; BAPI_PO_CHANGE 修改采购订单价格报错&#xff0c;请输入净价&#xff01; 2、先说下这个创建的函数 &#xff1a;BAPI_PO_CREATE1 ls_poitem-po_price ‘1’. " 价格采纳&#xff1a;1 总值 ls_poit…...