← 返回首页
文章已发布46 次阅读admin2026年10月31日8 分钟阅读八股分布式

分布式八股:CAP、限流算法、幂等与链路追踪

八股的读法改造版:分布式的第一性是「没有免费的选择」——CAP、限流、幂等、锁,都是把某种确定性换成概率承诺与校验闭环。

附件

  • fig-distributed-ratelimit.png(191 KB)下载

分布式八股:CAP、限流算法、幂等与链路追踪

主线:分布式的第一性是「没有免费的选择」——CAP、限流、幂等、锁,每一种机制都是把某一种确定性换成概率承诺与校验闭环。

一、公理与推论

「没有免费选择」之下一切考题可推:CAP 在分区时 C 与 A 互斥,注册中心因此有 AP / CP 双模;网络不保证顺序也不保证只投一次,所以总得有人负责——幂等、去重或状态机。

二、Q&A 速答

Q:CAP 与注册中心选型? 分区(P)无法避免,C 与 A 互斥:CP 同步复制可能拒绝服务,AP 异步复制继续可用但可能读到旧值。Nacos 同时支持 AP(临时实例)与 CP(持久实例),按服务性质选择。

本库锚点:Nacos namespace / group 全部 env 驱动,且 HTTP 服务发现与 Dubbo 注册用不同 group(Dubbo 侧加后缀隔离)——NacosDiscoveryProperties 的 group 是单值,混用会让标准 discovery client 找不到服务。

Q:限流算法演进? 固定窗口计数(临界两倍突刺)→ 滑动窗口(抚平突刺)→ 漏桶(恒定速率整流)→ 令牌桶(按预存令牌允许突发,弹性最好)。

本库实现:Redis ZSet 滑动窗口——时间戳为 score 写成员、ZREMRANGEBYSCORE 清过期、计数判定、超限 429 + 统一 ErrorResponse(code=RATE_LIMITED);整段逻辑 Lua 保证原子(读、删、计、写不原子时,并发计数互相覆盖)。维度按 KeyStrategy(IP / IP_PATH)构造 key;白名单放行 swagger 等路径;默认关、开启需 Redis。

Q:幂等常用方案? 唯一索引兜底(终局防线)→ 防重 token(先领后交)→ 状态机约束(非法迁移直接拒)→ 外部一次一性凭证。幂等解决「重试重复」,锁解决「并发互斥」——MQ 至少一次投递加客户端重试的世界里,两者常年同时上。

Q:链路追踪在分布式下怎么落地? traceId 从入口生成进 MDC、响应头回写,Dubbo 侧收口到单一 attachment envelope(consumer 只写、provider 只读),业务代码禁散装操作 RpcContext——跨进程链路不断,比背 Zipkin 架构更能打。

Q:旁路写怎么保证不拖垮主链路? 事件先进有界缓冲(满则丢弃并自暴计数),再批量落库——AuditIngestBuffer 的口径可平移到任何「容忍少量丢失的异步写」:审计日志、埋点、通知。

distributed ratelimit

三、思辨:概率与诚实的互换

谈 CAP 时不该问「该选哪个」,该问「愿意为什么付多少」——容忍多少旧值、接受多少拒绝,都是业务给定的数字。工程最诚实的姿态是:不追求无锁的完美,而明码标出哪一步允许「看起来会错」。DELETE 一条绑定后靠重启生效也好、允许一次缓冲丢弃也好、接受一次 429 也好——都可以是正确的,只要它们被诚实地说出并写进监控。

四、回到现实

三个动作:写分布式路径先标出「哪一步不原子」;限流阈值与降级策略进设计文档,不在 Redis 里现场调;跨进程凭据只走一个 envelope——第二个 key 出现就是失控开始。