-
用户只点了一次提交,因为网络超时客户端自动重试,结果同一笔订单被下了两次、款也扣了两次,我对着接口没做幂等设计这个坑排查大半天的复盘
一个让我对分布式与网络环境下的不确定性彻底敬畏的架构坑,后怕在出问题的不是某段写错的逻辑,而是一个我压根没考虑过的场景:同一个请求被处理了不止一次,而这在真实网络世界里是必然。用户投诉只下了一单却被扣两次款收到两份货,查日志确有两条几乎同时、内容完全一样的下单记录。下单接口逻辑朴实:扣库存、扣款、创建订单、发货。问题在于:用户点提交,请求到服务器其实已成功处理,但响应网络包回来路上超时丢失,客户端…- 0
- 0
-
一条扣款消息被消费了两次、用户被重复扣了钱,我查遍代码逻辑都没错、消息也确实只发了一条,我对着幂等性缺失和消息重投排查了大半天的复盘
半夜被电话叫醒的线上事故:有用户一笔订单被扣了两次钱。翻遍扣款逻辑没有任何会扣两次的分支,查消息队列确认上游那条扣款消息确实只发了一条。一条消息、一段没错的代码,怎么就扣了两次?排查大半天才理解分布式系统最易被忽略却最致命的设计缺失——幂等性,以及 MQ "至少投递一次"这个我从没认真对待的特性。事故链条是:消费者成功扣款,但 ACK 确认时网络抖动/重启导致 ACK 丢失,M…- 0
- 0
-
我的下单接口偶尔会给同一个用户生成两笔一模一样的订单、甚至重复扣款,我对着这些诡异的重复数据排查了大半天才真正理解幂等性的复盘
我的下单接口偶尔生成两笔几乎一模一样的订单、甚至同一笔消费扣两次款,两条订单除订单号外字段全同、时间差几百毫秒像被复制。我一开始以为是用户手抖点两次,排查日志才懂:重复大多不是点两次,而是"重试"——服务端处理成功了但返回响应超时,前端没收到成功就自动重试;调下游支付成功了但响应超时,本服务以为失败就重试;走 MQ 的 at-least-once 同一消息被消费多次。本质是网络…- 0
- 0
-
一个用户被扣了三次款:我在架构设计里漏掉"幂等"这两个字,酿成的那场重复支付资损事故,以及如何为写接口铸上一道牢靠的防重的锁
客诉转来:用户只下了一单,银行卡却被连扣三次款。还原现场——他网络卡顿、不耐烦连点了三下支付,三个请求涌向服务端,而我的支付接口对"看起来一样、却不知道是重复"的请求各处理了一遍,扣了三次款。根因是我漏掉了分布式系统里至关重要的幂等性。这篇从幂等的本质、为什么写接口必须幂等,讲到唯一约束/token/状态机三种正解、判断与执行的原子性等魔鬼细节,以及幂等背后的防御性架构思维。- 2
- 0
-
大促后对账发现重复扣款:一篇讲透接口幂等性设计
大促结束后的第二天上午,财务一条"对账对不平、几十个用户被重复扣款"的消息把我从复盘的轻松里一把拽出来,更夸张的是有人同一笔订单在库里躺着三四条记录。复盘下来真相平淡得后背发凉:流量冲顶时下单接口变慢,用户疯狂连点,客户端和网关又都配了超时重试,同一个请求被结结实实送进后端好几遍——而整个下单链路没有任何一处做了幂等保护。这篇文章从那次重复扣款事故出发,把接口幂等设计从头讲透:…- 8
- 0
-
Kafka 消费幂等性失守导致用户被重复扣款 ¥8.7w 的复盘:6 种幂等方案对比 + Outbox + CDC 落地
大促当晚 Kafka rebalance 触发重复消费,12 位用户被重复扣款,投诉炸了客服。11 天复盘揭开 3 个真凶:auto-commit 在 rebalance 时是定时炸弹、max.poll.interval.ms 超时、支付回调本身不幂等。本文 6 种幂等方案对比、Outbox + Debezium CDC 实战、灰度上线策略、压测脚本、7 条事件驱动纪律。- 6
- 0
-
重试与退避策略完全指南:从一次"重试把下游彻底打挂"看懂为什么失败不能无脑重试
2023 年我给一个交易服务接了好几个下游依赖调支付网关查库存发短信通知这些下游平时都挺稳但网络总会偶尔抖动某个下游也偶尔会超时一下第一版我处理得很顺手给每个下游调用都加上重试调用失败了就再试我设了重试 3 次每次失败后固定等 1 秒再来本地我把下游故意改成偶尔抛错一看重试确实生效了我心里很笃定重试嘛就是失败兜底的万能解药多试几次总能成可等它一上线一串问题冒了出来第一种最先把我打懵支付网关只是负载…- 4
- 0
-
接口幂等性设计完全指南:从一次"用户被扣了两次款"看懂前端置灰按钮为什么挡不住重复请求
2023 年我做一个电商的下单接口用户在前端点提交订单后端创建一笔订单扣一次款这件事我没多想就有了方案接口收到请求插入一条订单记录调支付返回成功第一版我做得很顺手为了防止用户手抖点两下我还特意在前端做了处理点击之后按钮立刻置灰本地点几下订单一笔一笔干净利落我心里很笃定重复提交嘛前端把按钮一灰用户想点第二下也点不了可等真实用户用起来一串问题冒了出来第一种最先把我打懵还是有用户创建了两笔一模一样的订单…- 2
- 0
-
消息队列幂等完全指南:从一次"积分被加了三次,库存被多扣"看懂 at-least-once 与重复消费
2022 年我给一个电商订单系统接消息队列用户下单后扣库存加积分发通知短信这些后续动作全部丢进 MQ 异步去做怎么消费这些消息这件事我压根没多想第一版我做得很顺手消费者从队列里取一条消息该扣库存扣库存该加积分加积分处理完了 ack 确认一下就完事了本地拿一批消息一测真不错下一单消费一条库存减一积分加上分毫不差我心里很笃定消息队列嘛我发一条消费者收一条处理一条一条消息对应一次处理 MQ 这种成熟中间…- 0
- 0
-
接口幂等性完全指南:从一次"用户点了两下、扣了两次钱"看懂幂等设计
2023 年我做一个支付下单接口。逻辑很简单:用户点支付,前端把请求发到后端,后端扣款然后创建订单。第一版做得很直接本地测上线初期都挺好。可上线一段时间后客服转来一个投诉:有用户说自己只买了一件东西却被扣了两次钱后台还生成了两个一模一样的订单。我翻日志发现同一个用户同样的金额几乎同一时刻有两条一模一样的请求打进了后端。我第一反应是用户手抖点了两下让前端在点击后把按钮禁用掉结果还是有重复。我又翻了更…- 4
- 0
-
接口幂等性完全指南:从一次"网络抖动让用户被扣了两次款"看懂幂等设计
2023 年我负责一个支付下单接口,扣余额、生成订单、返回成功。测试一路绿,上线几个月后客服转来投诉:一个用户只买了一次,余额被扣两次,订单列表躺着两笔一模一样的订单。翻日志才发现那个请求在服务器上确确实实被完整执行了两次。问题不在我的逻辑,在它之外:用户网络抖了一下,第一次请求其实已处理完,但响应在回程丢了,前端超时自动重发,第二次又被老老实实执行了一遍。我以为接口自己不写 bug 就不会重复扣…- 0
- 0
-
幂等性与分布式锁完全指南:幂等 Token、Redis 锁与 Snowflake ID
"用户重复点击下单按钮,产生了两个订单。""扣款接口因网络重试调用了两次,用户被扣了两次钱。""消息队列重发,业务被执行两次。"—— 这些场景的根源都是同一个:缺乏幂等性。这篇文章把幂等性、分布式锁、分布式 ID 这三个紧密相关的话题一次讲透,因为它们经常组合出现在解决方案里。 幂等性的定义 简单说:同一个操作执行 N 次和执行 1 次效…- 9
- 0
幂等性
幸运之星正在降临...
点击领取今天的签到奖励!
恭喜!您今天获得了{{mission.data.mission.credit}}积分
我的优惠劵
-
¥优惠劵使用时效:无法使用使用时效:
之前
使用时效:永久有效优惠劵ID:×
没有优惠劵可用!












