← 返回思维链目录

分布式思维链

看到数据不一致、锁失效、重复消费、雪崩,顺藤摸瓜找到根因

1. 分布式锁失效:为什么超卖还发生

现象加了分布式锁,秒杀还是超卖了
本质:分布式锁的目的是"跨进程互斥",但锁可能因为过期续期、网络分区、时钟不同步等原因失效,导致多个进程同时拿到锁。
🌊 顺藤摸瓜
① 锁过期
业务执行超过锁过期时间 → 锁自动释放 → 别人拿到锁 → 原进程回来还以为有锁 → 两个进程同时执行 → 解决:看门狗续期(Redisson)
锁过期看门狗续期Redisson
② 释放错锁
A 的锁过期了 B 拿到,A 执行完删了 B 的锁 → 解决:value 存唯一标识,删前判断是不是自己的(Lua 原子)
删错锁value 唯一标识Lua 原子删
③ Redis 主从切换
主节点加锁还没同步到从就挂了 → 从提升为主,锁丢了 → 解决:Redlock(多个独立 Redis 节点过半加锁)
主从切换丢锁RedlockZookeeper(更可靠)
分布式锁不能只 SET NX,还要:过期 + 续期 + 唯一标识 + 原子删。生产用 Redisson 封装好了。

2. 分布式数据不一致

现象多个服务操作同一份数据,偶发不一致
本质:分布式系统跨进程跨网络,操作无法原子完成(要么部分成功,要么网络超时),导致中间状态。
🌊 顺藤摸瓜
① 分布式事务
跨服务操作要么全成功要么全失败 → 2PC/3PC(强一致但慢)→ TCC(Try-Confirm-Cancel,业务侵入)→ Saga(长事务,补偿)→ 本地消息表 + MQ(最终一致,最常用)
2PCTCCSaga 补偿本地消息表+MQ
② 幂等性
网络超时重试 → 可能重复扣款 → 解决幂等:同一操作执行多次结果一致 → 唯一 ID + 去重表 / 状态机 / 乐观锁版本号
幂等设计唯一 ID 去重状态机版本号
③ CAP 取舍
网络一定断(P 必选)→ CP(银行,宁可不可用也不数据错)/ AP(社交,可用优先短暂不一致)→ 大多选 AP + BASE 最终一致
CAPCP vs APBASE 最终一致

3. MQ 重复消费 / 丢失

现象用户收到两条短信,或者消息丢了没处理
本质:MQ 的消息投递是至少一次(At Least Once),网络超时会重试,所以消费端必须幂等。丢失则是生产端没存住或消费端 ACK 时机错。
🌊 顺藤摸瓜
① 重复消费
消费者处理完还没 ACK 就挂了 → MQ 重投 → 重复消费 → 解决:消费端幂等(唯一 ID 去重表 / Redis 标记)
At Least Once消费端幂等唯一 ID 去重
② 消息丢失
三个环节可能丢:① 生产端(发之前挂了 → 本地消息表);② MQ(开启持久化);③ 消费端(处理完再 ACK,别先 ACK 再处理)
生产确认MQ 持久化手动 ACK
③ 顺序消费
消息要按顺序(增删改)→ 同 key 进同 partition(单线程消费)→ Kafka 按 partition 有序
同 key 同 partition单线程消费

4. 雪崩:一个服务挂全挂

现象下游服务超时,调用方线程池打满,整条链路全挂
本质:服务 A 调 B,B 慢导致 A 的线程被占满,A 也慢,A 的调用方也跟着挂 —— 级联失败
🌊 顺藤摸瓜
① 超时
调用下游必须设超时 → 别无限等 → 超时快速失败释放线程
超时设置快速失败
② 熔断
下游错误率超阈值 → 熔断(一段时间内直接失败,不调下游)→ 给下游恢复时间 → Sentinel/Hystrix
熔断Sentinel错误率阈值
③ 降级
下游挂了返回兜底数据(默认推荐/缓存数据)→ 保核心功能可用
降级兜底返回缓存
④ 限流
请求量超过承受 → 限流(令牌桶/漏桶)→ 挡住洪峰保护系统
限流令牌桶Sentinel
高可用三板斧:超时(别无限等)+ 熔断(挂了快速失败)+ 降级(返回兜底)+ 限流(挡洪峰)。核心:故障隔离,防止级联。

总结

现象本质第一反应
锁失效超卖过期/删错/主从丢锁看门狗续期+唯一标识+Redlock
数据不一致跨进程操作无法原子分布式事务+幂等+CAP 取舍
重复消费At Least Once 重试消费端幂等(去重表/Redis)
雪崩全挂级联失败超时+熔断+降级+限流
本质:分布式的所有问题都源于"网络不可靠 + 操作无法原子"。解决方案大多是"接受最终一致 + 幂等 + 故障隔离"。