重试是解药还是毒药?聊聊幂等性

分布式系统里有一句被说烂了的话:"失败就重试" 。但真正踩过坑的人知道,重试本身才是很多事故的制造者------它会把一次偶发失败,放大成一次数据事故。

这篇文章只讲一件事:什么时候可以重试,什么时候重试等于自毁。

一、重试为什么危险:它假设了"没做成"

重试的隐含前提是:上一次操作没有生效。

但网络超时、连接被重置、进程被杀------这些"失败信号"只说明你没收到结果,不说明对方没做。请求可能已经到达、已经执行、只是响应在回程丢了。

于是重试就变成了**"再执行一次"**,而不是"再试一次"。

  • 转账:扣两次钱;
  • 下单:下两个单;
  • 发消息:对方收到两条。

**这类问题的学名叫"至少一次(at-least-once)语义",它是绝大多数 RPC 与消息中间件的默认行为。**注意是"至少",不是"恰好"。

二、判据:这个操作"执行两次"会怎样?

判断能不能无脑重试,只需要问一个问题:

这个操作重复执行一次,结果会和执行一次一样吗?

  • 一样 ⇒ 它是幂等 的(如 SET status = 'paid'、DELETE WHERE id=1),可以放心重试;
  • 不一样 ⇒ 它是非幂等 的(如 balance = balance - 100、INSERT),必须加保护才能重试。

注意:UPDATE ... SET x = 5 是幂等的,而 UPDATE ... SET x = x + 1 不是------同一个动词,差别在"赋绝对值"还是"基于当前值"。

三、四种常用的保护手段

1. 幂等键(Idempotency Key) 调用方生成一个全局唯一键随请求发送,服务端首次见到就执行并记录结果,之后再见到同一个键直接返回上次的结果。这是最通用的一种,Stripe 等支付 API 用的就是这个。

要点:键要由调用方 生成(服务端生成没有意义),并且要落库 、要有过期策略。

2. 唯一约束 把"业务上不允许重复"这件事交给数据库 :UNIQUE(order_id, payment_seq)。写入冲突就说明已经做过------这不是错误,是重复请求被正确拦下。

3. 状态机 + 条件更新 不要让"状态"可以被随意改写。把操作表达成**"从 A 状态迁移到 B 状态"**:

sql 复制代码
UPDATE orders SET status='paid' WHERE id=? AND status='pending';

看受影响行数 :1 表示这次真的迁移了;0 表示它已经被处理过(或状态不对)------两种都不该报错,而应各自有分支。

4. 去重层 / 消费位点 消息队列场景下,消费端要么用位点 (只处理一次),要么用去重表 (记录已处理的消息 ID)。不要指望"消息只投递一次"。

四、几个容易忽略的细节

  • 重试要有上限和退避:固定间隔重试会在故障时形成"重试风暴",把下游打死。指数退避 + 抖动(jitter)是标配;
  • 区分"可重试"与"不可重试" :5xx / 超时通常可重试;而 400 / 业务校验失败重试一万次也不会变对;
  • 超时不等于失败 :多数 RPC 的读超时只代表"我没等到响应",不代表服务端没执行------这正是幂等键存在的理由;
  • 幂等键的粒度:按"一次业务意图"生成,而不是按"一次 HTTP 请求"生成,否则重试时键会变,保护就失效了。

五、一句话总结

重试的正确前提不是"失败了",而是"重复执行无害"。

所以顺序应该是:先让操作幂等,再允许重试------反过来做,就是拿运气当架构。


本文讨论的是通用的分布式系统设计原则,不涉及任何具体系统或业务。

相关推荐
god_cvz2 小时前
第二章:6、对话记忆与引用标注
后端·ai编程
用户125758524362 小时前
Golang后台管理框架推荐:XYGo Admin与devinggo怎么选?
后端·go·ai编程
陽清AI一人企业2 小时前
30岁程序员别再卷算法,转行最缺的是能驻场的活
ai编程·创业
用户842558130872 小时前
退出码 0、日志干净,但一件事也没干成:自动化脚本的 9 种静默失败
ai编程
单向箔2 小时前
08|一套可复制的 AI Coding 流程:从需求到提交怎么走
人工智能·prompt·ai编程
自律懒人2 小时前
openJiuwen 企业级 AgentOS 实测:4 层架构 + 5 步部署,多智能体协作省 60% Token
ai编程
熊出没3 小时前
从Copilot到Agent:AI编程工作流的重构与落地实践
软件工程·copilot·ai编程·ai agent
Sammyyyyy4 小时前
jev-ultrafast 实战:浏览器操作代理加本地 AI 网关,把云控制台配置做成自动化流水线
运维·人工智能·自动化·ai编程·servbay
啵啵啵鱼4 小时前
对数据的增删改查
数据库·mysql·ai·idea·ai编程·navicat·obsidian