-
我用 Redis 加了分布式锁保护临界区,以为万无一失,结果偶发两个进程同时进了临界区、一个进程还把别人的锁给删了:一次分布式锁实现陷阱的深度复盘
我有段临界区代码用 Redis 加了分布式锁保护:SET lock NX EX 30 抢锁、处理完 DEL 释放,以为万无一失。可线上偶发两个进程同时进入临界区的数据错乱,有时还有一个进程把另一个进程正持有的锁删了。推演时序才看明白这锁有两个致命漏洞:漏洞一,锁 EX 30 过期了但业务还没跑完,锁自动释放、B 抢到、A 和 B 同时在临界区;漏洞二,释放时直接 DEL 没校验是不是自己的锁,A …- 0
- 0
-
一个没做幂等的消息队列消费者,因为一次网络抖动把同一条扣款消息消费了两次,给用户活生生扣了两次钱:一次消息重复消费与幂等缺失的深度复盘
半夜被叫醒处理资损:一笔订单被扣了两次款,有两条几乎一致的扣款流水,可同一笔订单我们只发了一条扣款消息。翻 MQ 投递日志才看清:消息队列是 at-least-once(至少一次)投递、宁可重复不愿丢消息,那次扣款服务已成功扣款,但返回 ack 时网络抖动、ack 没送达,MQ 以为没处理成功便重新投递,而消费者没做幂等、又扣了一次。本文讲透 MQ 三种投递语义与为何必须幂等,给出数据库唯一约束/…- 0
- 0
-
一个 Redis 分布式锁的过期时间没扛住业务耗时,锁提前自动释放让两个线程同时进了临界区、还互相误删了对方的锁:一次分布式锁失效的深度复盘
用 Redis 分布式锁保证同一笔账只有一个节点处理,跑了大半年都好好的,直到对账量大、业务跑了 40 秒、超过了锁的 30 秒过期时间——锁中途自动释放,第二个线程进了临界区两线程同时处理,第一个线程干完 del 又删掉了第二个线程的锁,锁彻底形同虚设。本文讲透分布式锁的两大核心难题(过期时间两难、误删),给出唯一标识+Lua 原子校验删除防误删、看门狗自动续期解决过期、生产用 Redisson…- 0
- 0
-
一个调用第三方接口忘了设超时的 HTTP 客户端,把整个服务的线程池拖到全部 hang 死:一次没有超时引发级联雪崩的深度复盘与韧性正解
核心服务突然大面积 504,jstack 一看几百个工作线程全卡在调用第三方风控接口的 socketRead0 上一动不动——而那个 HTTP 客户端压根没设超时。对方发布卡了几十秒,我方每个线程无限期等待,线程池被占满,连不相干的接口也全挂了,级联雪崩。本文从满屏 hang 死的线程堆栈讲起,剖析没超时如何耗尽线程池拖垮全局,给出设超时(底线)+熔断+降级+线程隔离(舱壁)的韧性组合拳,并梳理常…- 0
- 0
-
下游服务只是变慢了根本没挂,可我的服务却被它活活拖死、彻底无响应了:一个没设读取超时的 HTTP 调用引发整个系统雪崩的深度复盘
下游服务 B 没挂,只是变慢了(从几十毫秒飙到几十秒),可我的服务 A 却跟着彻底挂了。排查发现 A 的线程池被占满——所有线程都卡在"调 B、等 B 返回"上一动不动。根因是我调 B 的 HTTP 客户端没设读取超时:B 一慢,线程就无限期傻等,高并发下线程一个个被卡死、占满线程池,A 也就垮了。这篇从"无限等待"如何传导成雪崩讲到连接+读取超时的正解、熔…- 0
- 0
-
一个用户被扣了三次款:我在架构设计里漏掉"幂等"这两个字,酿成的那场重复支付资损事故,以及如何为写接口铸上一道牢靠的防重的锁
客诉转来:用户只下了一单,银行卡却被连扣三次款。还原现场——他网络卡顿、不耐烦连点了三下支付,三个请求涌向服务端,而我的支付接口对"看起来一样、却不知道是重复"的请求各处理了一遍,扣了三次款。根因是我漏掉了分布式系统里至关重要的幂等性。这篇从幂等的本质、为什么写接口必须幂等,讲到唯一约束/token/状态机三种正解、判断与执行的原子性等魔鬼细节,以及幂等背后的防御性架构思维。- 2
- 0
-
大促后对账发现重复扣款:一篇讲透接口幂等性设计
大促结束后的第二天上午,财务一条"对账对不平、几十个用户被重复扣款"的消息把我从复盘的轻松里一把拽出来,更夸张的是有人同一笔订单在库里躺着三四条记录。复盘下来真相平淡得后背发凉:流量冲顶时下单接口变慢,用户疯狂连点,客户端和网关又都配了超时重试,同一个请求被结结实实送进后端好几遍——而整个下单链路没有任何一处做了幂等保护。这篇文章从那次重复扣款事故出发,把接口幂等设计从头讲透:…- 8
- 0
-
MySQL 主从读写分离 read-your-write 缺失 3 年酿成日均 12 万次读到旧值的复盘:sticky + hint + cache 三层一致性方案落地
读写分离上线 3 年默认所有 SELECT 走从,从未系统设计哪些场景必须读主。客诉 37 单挖出日均 12 万次读到旧值事件根因。5 天复盘 + 4 层物理延迟拆解 + 7 种 read-your-write 方案横向对比 + 决策树 + 9 条读写一致性纪律,真实事件量降到日均 180 次。- 3
- 0
-
Kafka 消息队列工程化完全指南:从一次"acks=1 丢 3000 单订单损失 50 万"看懂为什么 send/poll 远远不够
2021 年我加入一家直播带货公司接手订单系统当时下单链路是用户下单写 MySQL 同步调库存调营销调通知调推送 5 个下游服务每个 100ms 端到端 500ms 直播间瞬时下单峰值 8000 QPS 链路雪崩我决定引入 Kafka 把下游全异步化觉得 Kafka 高吞吐低延迟上 3 broker 8 partition 应该够用改造后压测确实漂亮 8000 QPS 端到端 50ms 老板很满意…- 0
- 0
-
Kafka 消息可靠性工程化完全指南:从一次"机房故障 200 条订单消息丢失"看懂为什么默认配置远远不够
2023 年我们公司有一套订单系统上游产生事件下游有 6 个消费服务用 Kafka 做异步消息总线一开始我接手时配置很标准 3 个 broker 默认 partition 数 ack=1 producer 自动批 consumer auto-commit 看起来该有的都有测试环境跑得也挺顺但上线半年我们陆续踩了一堆坑第一种最让我傻眼某次机房故障一个 broker 挂了我以为副本机制应该自动转结果有…- 0
- 0
-
gRPC 微服务超时与重试工程化完全指南:从一次"下游慢 800ms 上游 5 个服务全部雪崩"看懂为什么加 timeout 远远不够
2023 年我们公司有一套基于 gRPC 的微服务架构十几个服务互相调用拓扑大概有三四层深接手时表面看挺平静 QPS 不算高响应时间也还行可三个月里我们陆陆续续出了几次让我刻骨铭心的故障第一次是周五晚上一个下游的搜索服务因为索引重建延迟变高从 50ms 涨到 800ms 结果上游所有依赖它的服务的线程池被打满整个调用链上的 5 个服务全部超时雪崩业务被打挂 30 分钟第二次最莫名其妙某个接口压测时…- 2
- 0
-
Redis 缓存穿透/击穿/雪崩三大场景实战指南:从一次"大促零点缓存命中率从 98% 掉到 12%"看懂为什么 Redis 加 TTL 远远不够
2022 年我所在的电商团队做大促活动零点开抢的瞬间整个商品详情页接口的 RT 从平时的 80 毫秒飙升到了 8 秒缓存命中率从平时的 98% 掉到了 12% 我当时正在值班看着监控曲线直接懵了我们的缓存策略其实做得不算简单商品详情用 Redis 缓存了 TTL 半小时按理说大促前已经预热过了为什么命中率会掉这么狠后来复盘才发现这一夜爆出了不止一个问题第一个问题最常见某个爆款商品的缓存恰好在零点过…- 0
- 0
-
Kafka 消费者组与 rebalance 工程实战:从一次"凌晨 3 点整组消费停顿 20 分钟"看懂为什么慢消息能拖垮你的消费链路
2023 年我接手了一套基于 Kafka 的订单事件处理链路上游一天大概几亿条事件下游有十几个消费者组各自处理不同业务接手的第一个月一切都很顺没出什么大事让我心里很笃定 Kafka 这东西嘛只要 topic 分区数够多消费者数量配得上就完事了直到有一天凌晨 3 点告警群里炸了订单状态回写延迟从平时的 200 毫秒涨到了 40 秒我爬起来排查发现下游某个消费者组在不停 rebalance 平均每 3…- 2
- 0
-
接口幂等性设计完全指南:从一次"用户被扣了两次款"看懂前端置灰按钮为什么挡不住重复请求
2023 年我做一个电商的下单接口用户在前端点提交订单后端创建一笔订单扣一次款这件事我没多想就有了方案接口收到请求插入一条订单记录调支付返回成功第一版我做得很顺手为了防止用户手抖点两下我还特意在前端做了处理点击之后按钮立刻置灰本地点几下订单一笔一笔干净利落我心里很笃定重复提交嘛前端把按钮一灰用户想点第二下也点不了可等真实用户用起来一串问题冒了出来第一种最先把我打懵还是有用户创建了两笔一模一样的订单…- 2
- 0
-
分布式锁完全指南:从一次"多实例部署后库存被超卖"看懂为什么单机锁挡不住分布式并发
2023 年我做一个电商的库存扣减接口用户下单要先扣库存怎么保证不会超卖这件事我没多想就有了方案加锁第一版我做得很顺手在扣库存的那段代码外面用一把锁圈起来同一时刻只放一个请求进去查库存够不够够就扣不够就拒绝本地一压测真不错并发再高库存也扣得分毫不差从来不会扣成负数我心里很笃定我都加锁了临界区同一时刻只有一个请求并发安全这不就有了可等这个接口真正上线被部署成多个实例扛起生产流量一串问题冒了出来第一种…- 4
- 0
-
消息队列幂等完全指南:从一次"积分被加了三次,库存被多扣"看懂 at-least-once 与重复消费
2022 年我给一个电商订单系统接消息队列用户下单后扣库存加积分发通知短信这些后续动作全部丢进 MQ 异步去做怎么消费这些消息这件事我压根没多想第一版我做得很顺手消费者从队列里取一条消息该扣库存扣库存该加积分加积分处理完了 ack 确认一下就完事了本地拿一批消息一测真不错下一单消费一条库存减一积分加上分毫不差我心里很笃定消息队列嘛我发一条消费者收一条处理一条一条消息对应一次处理 MQ 这种成熟中间…- 0
- 0
-
分布式 ID 生成完全指南:从一次"两台机器同时生成了一样的订单号"看懂雪花算法
2021 年我做一个订单系统要给每一笔订单生成一个全局唯一的订单号。第一版我做得很省事订单表是 MySQL 我直接用了表的自增主键当订单号。本地一测完美每插一条订单 ID 自动加一从不重复。我心里很踏实生成唯一 ID 嘛数据库自增不就行了要么随手 UUID 一下。可等系统真正长大扛着真实的业务量一串问题冒了出来。第一种最先把我打懵订单量上来后我做了分库分表把订单拆到两个库结果两个库各自从 1 开始…- 0
- 0
-
接口幂等性完全指南:从一次"用户点了两下、扣了两次钱"看懂幂等设计
2023 年我做一个支付下单接口。逻辑很简单:用户点支付,前端把请求发到后端,后端扣款然后创建订单。第一版做得很直接本地测上线初期都挺好。可上线一段时间后客服转来一个投诉:有用户说自己只买了一件东西却被扣了两次钱后台还生成了两个一模一样的订单。我翻日志发现同一个用户同样的金额几乎同一时刻有两条一模一样的请求打进了后端。我第一反应是用户手抖点了两下让前端在点击后把按钮禁用掉结果还是有重复。我又翻了更…- 4
- 0
-
接口幂等设计完全指南:从一次"网络重试把用户扣款扣了两次"看懂幂等
2019 年我做一个电商的下单支付接口,逻辑很直白:用户点提交订单,后端创建一条订单记录,从余额里扣钱,返回订单号。本地测试一切正常,上线后也好好的。直到客服转来一个投诉:一个用户只下了一单却被扣了两次钱。我查日志发现这个用户的下单接口在几秒内被调用了两次,参数一模一样,数据库里多了两条几乎相同的订单,扣款也执行了两遍。我第一反应是用户手抖点了两次,可继续查下去发现根本不是——很多重复请求用户只点…- 2
- 0
-
分布式锁完全指南:从一次"扩容后对账任务跑了三遍、结算被重复打款"看懂分布式锁
2023 年我维护一个对账定时任务,每天凌晨核对订单和支付流水、生成结算单、发结算邮件。单实例跑了大半年稳稳当当,直到运维把服务从 1 个实例扩容到 3 个,第二天就出事:同一用户收到三封结算邮件,有几笔结算被重复打款。翻代码一行 bug 都没有,盯着部署结构才反应过来:定时任务代码被原封不动部署到 3 个实例上,凌晨那一刻 3 个实例各自都跑了一遍。我以为代码里加了 Lock 就并发安全,真相是…- 0
- 0
-
接口幂等性完全指南:从一次"网络抖动让用户被扣了两次款"看懂幂等设计
2023 年我负责一个支付下单接口,扣余额、生成订单、返回成功。测试一路绿,上线几个月后客服转来投诉:一个用户只买了一次,余额被扣两次,订单列表躺着两笔一模一样的订单。翻日志才发现那个请求在服务器上确确实实被完整执行了两次。问题不在我的逻辑,在它之外:用户网络抖了一下,第一次请求其实已处理完,但响应在回程丢了,前端超时自动重发,第二次又被老老实实执行了一遍。我以为接口自己不写 bug 就不会重复扣…- 0
- 0
分布式系统
幸运之星正在降临...
点击领取今天的签到奖励!
恭喜!您今天获得了{{mission.data.mission.credit}}积分
我的优惠劵
-
¥优惠劵使用时效:无法使用使用时效:
之前
使用时效:永久有效优惠劵ID:×
没有优惠劵可用!





















