常见的幂等方案

1. 过滤-去重型(显式挡回重复包)

思路:在业务逻辑之前,先检查"这条请求 / 这条消息是不是第一次见到"。

常见实现

• 数据库唯一索引:INSERT ... ON CONFLICT DO NOTHING

• 去重表 / Redis SET:SADD msgId 看返回值 0/1

• 带 TTL 的布隆过滤器:高 QPS 场景减小内存

优点

• 对已有系统侵入小,只要给消息加 msgId

• 过滤失败后可以"啥也不做"直接 ACK,不会二次执行。

缺点

• 需要额外存储去重键,热点写压力大。

• 强制把"是否重复"与"业务逻辑"分离,代码路径分叉。

• 时间窗口过长会造成键无限增长;过短又可能误判"新老交叉"。

适用

支付、扣款、库存扣减等"不能多扣一分钱/一件货"的硬幂等场景。


2. 状态幂等型(让同一操作幂次方 = 1)

思路:业务本身就是一棵状态机,外部多发同一个动作不再产生新副作用。

实现方式

• 不可变资源:PUT /users/42/address 多次覆盖写,最终状态一致。

• CAS / 乐观锁:只在 version=N 时成功;失败说明已经处理过。

• 状态字段:订单 status = PAID 再收到支付回调直接忽略。

优点

• 内部数据结构最简,复用现成行记录。

• 不依赖额外键值表,天然水平扩展。

• 重放/回溯也安全。

缺点

• 并非所有业务都能"覆盖写"------扣减库存、累计积分就不是幂等操作。

• 状态设计稍有不慎会出现"订单半付款"之类边界态。

适用

资源更新(配置中心、用户资料)、软删除标记、流式统计覆盖写。

怎样选

  1. 一次性副作用(扣钱 / 发货) → 过滤-去重 +/or 事务-原子
  2. 状态覆盖(用户资料) → 状态幂等

相关推荐
用户6736132368552 分钟前
掌握 DNF,openEuler 软件安装速度翻倍!
后端
用户0524832491763 分钟前
在 openEuler 上部署 YOLOv8 实现实时目标检测
后端
稚辉君.MCA_P8_Java5 分钟前
Gemini永久会员 Java 返回最长有效子串长度
java·数据结构·后端·算法
极光代码工作室7 分钟前
基于SpringBoot的停车场收费管理系统的设计与实现
spring boot·后端·产品运营
喵个咪10 分钟前
微服务技术选型:从生态架构视角看go-kratos的不可替代性
后端·go
Wokoo720 分钟前
C/S 架构与 B/S 架构:核心差异 + 选型指南
分布式·后端·中间件·架构
g***267922 分钟前
Springboot中mybatis的使用
spring boot·后端·mybatis
程序员爱钓鱼35 分钟前
Node.js 编程实战:安装 Node.js 与 npm / yarn
后端·node.js·trae
CodeSheep40 分钟前
裁员为什么先裁技术人员?网友一针见血
前端·后端·程序员