← 返回题目列表

分布式限流怎么做?单机限流和全局限流有什么区别?

高频 中等 第 5 / 26 题 更新于 2026/07/28
分布式限流Redis网关限流服务治理

简化版

单机限流只限制当前实例上的请求量,适合保护本机资源;分布式限流要限制整个集群、某个用户、某个接口或某个租户的总请求量。常见方案有网关统一限流、Redis 计数器或 Lua 令牌桶、限流中间件、本地限流加动态配额。全局限流更准确,但依赖中心存储,延迟和可用性成本更高;本地限流性能好,但全局精度差。

详细版

单机限流通常用本地令牌桶、滑动窗口或信号量,开销低,适合限制单实例 CPU、线程池、连接池。问题是服务有多个实例时,每个实例各限 100 QPS,10 个实例就可能放行 1000 QPS,无法控制全局额度。

分布式限流需要共享状态。最常见是网关层按接口、用户、IP、租户限流;也可以用 Redis INCR + EXPIRE 做固定窗口,用 Lua 保证令牌桶或滑动窗口操作原子性。更大规模时会用本地限流加集中配置,把全局配额拆到各实例,减少每个请求访问 Redis。

面试要讲取舍:全局准确性、性能开销、Redis 故障兜底、热点 key、时钟一致性、限流粒度和业务优先级。

完整版教学

一、为什么需要分布式限流

在单体或单实例系统里,本地限流就能保护服务。但微服务通常有多个实例,流量经负载均衡分散到不同机器。如果每台机器只知道自己的请求量,就无法判断整个集群是否超量。比如一个接口全局只能承受 1000 QPS,部署 20 个实例后,每个实例限 100 QPS,就会放行 2000 QPS。

分布式限流的目标是控制全局资源使用,例如某个接口总 QPS、某个用户调用次数、某个租户配额、某个活动入口流量。它比单机限流更接近业务约束。

二、网关限流

网关限流是最常见方案。所有外部请求先经过 API 网关,在网关按 IP、用户、接口、AppKey、租户等维度做限流。优点是入口统一,能在请求进入后端服务前挡住过载流量,配置和观测也集中。

缺点是内部服务间调用不一定经过网关,网关本身也要高可用。如果网关限流规则太复杂,可能成为性能瓶颈。因此很多系统会采用网关入口限流加服务内部自我保护的组合方式。

三、Redis 分布式限流

Redis 常用于共享限流状态。简单固定窗口可以用 INCR 和 EXPIRE:每个维度一个 key,每次请求加一,超过阈值拒绝。为了保证原子性和避免并发竞态,复杂算法通常用 Lua 脚本一次完成读、算、写。

Redis 也能实现令牌桶或滑动窗口。令牌桶要保存当前令牌数和上次补充时间;滑动窗口可以用 ZSET 保存请求时间戳并清理窗口外数据。固定窗口简单但边界突刺明显,滑动窗口精确但成本更高,令牌桶在性能和弹性之间比较均衡。

四、本地限流加动态配额

每个请求都访问 Redis 会增加延迟,也可能把 Redis 打成热点。高并发场景常用本地限流加动态配额:控制面根据全局阈值、实例数、负载情况,把额度分配给每个实例;实例在本地用令牌桶快速判断。配额定期刷新或按负载调整。

这种方案性能好,但全局精度不如强中心化限流。实例上下线、负载不均、配置延迟都可能导致短时间偏差。它适合大流量、允许一定误差的场景。

五、故障兜底和热点问题

分布式限流依赖 Redis 或控制面时,要设计故障兜底。Redis 不可用时,是放行、拒绝,还是退化为本地限流,要按业务风险决定。核心交易接口可能宁可本地保守限流,开放接口可能允许短时间放行但告警。

热点 key 也要注意。按全站接口维度限流时,所有请求打同一个 key,Redis 压力会很大。可以做分片 key、本地预扣令牌、批量获取令牌、网关分层限流等优化。

六、面试追问与工程边界

常见追问是单机限流和分布式限流怎么选。保护单实例资源用本地限流,控制全局业务配额用分布式限流。真实系统一般两者都有:网关做全局入口保护,服务内部做线程池、连接池、依赖调用保护。

另一个追问是限流维度如何设计。维度越细越公平,但状态越多、成本越高。常见维度包括 IP、用户、租户、接口、来源 App、业务场景。对登录用户通常按用户或租户限,对匿名流量常按 IP 或设备指纹限。

七、落地设计清单

分布式限流落地时,要先明确限流维度。按 IP 限适合防匿名访问和爬虫,按用户限适合保护个人配额,按租户限适合 SaaS 多租户公平性,按接口限适合保护服务容量,按 AppKey 限适合开放平台。维度选错会导致要么误伤,要么挡不住真正的热点来源。

其次要设计层级。网关做入口全局限流,服务内部做本地自我保护,下游依赖调用再做依赖级限流。这样即使网关规则漏掉,服务也能保护自己;即使全局 Redis 限流不可用,本地限流也能兜底。高流量系统通常不会每个请求都强依赖中心存储,而是用本地令牌、批量预取、分片 key 或动态配额降低中心压力。

八、常见误区和故障兜底

第一个误区是以为 Redis 限流天然可靠。Redis 自身可能故障,热点 key 可能打满单分片,网络抖动会增加接口延迟。限流系统出问题时必须有降级策略:可以退化为本地限流,可以保守拒绝,也可以短时放行并告警,具体取决于业务风险。

第二个误区是追求绝对精确。高并发分布式限流通常需要在精度、性能和可用性之间取舍。比如本地配额可能短时间超放,但性能好;中心化 Lua 令牌桶更准确,但延迟和热点压力更高。面试时把取舍讲清楚,比只说 Redis INCR 更成熟。 另外,开放平台类限流要特别关注“公平性”。如果只按接口总 QPS 限流,大客户或恶意调用方可能把额度全部吃掉,导致其他正常租户被误伤。因此常见做法是先做全局保护,再做租户级、用户级或 AppKey 级配额,最后对异常 IP 做更细粒度限制。这样既能保护系统总容量,也能避免单个调用方挤占公共资源。

九、常见误区与追问

这道题不能只背概念,要把「分布式限流」放回真实分布式系统里解释:谁发起、谁协调、状态如何变化、失败后怎么兜底,以及它和性能、可用性、一致性的取舍。

回答层次要讲清的内容容易漏掉的边界
核心结论分布式限流在多实例场景下共享计数或令牌状态,避免每个节点本地限流导致总量超标不要停在名词解释
流程机制请求进入任一实例 -> 计算限流 key -> 访问 Redis 或限流服务 -> 原子扣减令牌或计数 -> 通过则放行 -> 超限返回 429 或降级说明触发方、参与方、状态变化和兜底
工程取舍5 个网关实例各自本地限 100 QPS,总入口可能达到 500 QPS;全局限流应共享状态为 100 QPS治理组件是为了控制故障半径,不是让下游无限扛流量
分布式限流 面试拆解:
1. 请求进入任一实例
2. 计算限流 key
3. 访问 Redis 或限流服务
4. 原子扣减令牌或计数
5. 通过则放行
6. 超限返回 429 或降级

记忆钩子:先定位治理目标,再拆限流、熔断、降级、重试、追踪、灰度和幂等边界;回答时要紧扣「分布式限流」这道题,不要把相邻概念混成一段泛泛的分布式套话。

  • 误区:单机限流在集群里仍是全局阈值。 每个实例各限一次会放大总阈值。
  • 误区:分布式限流只需要 Redis INCR。 还要考虑窗口、过期、原子性、热点 key 和 Redis 可用性。
  • 误区:限流一定要拒绝请求。 也可以排队、降级、返回缓存或按优先级放行。
  • 追问:常见全局限流方案有哪些? Redis+Lua、集中限流服务、网关插件、Sentinel 集群限流。
  • 追问:Redis 挂了怎么办? 可选择失败开放、本地兜底限流或失败关闭,取决于业务风险。
  • 追问:限流维度怎么选? 按接口、用户、IP、租户、AppKey、地域等组合。

十、加强记忆

分布式限流就是“多个实例共享一个额度”。网关限流入口统一,Redis 限流全局准确,本地配额性能更好但有误差。单机限流保护本机资源,全局限流保护业务总容量。回答时一定讲 Redis 原子性、热点 key、故障兜底和本地降级。