周末的网红奶茶店门口永远排着长队。店长心里清楚,后厨一分钟最多只能做出 5 杯招牌奶茶——如果任由顾客涌到柜台,后厨要么手忙脚乱做错配方,要么直接崩溃停业。所以聪明的店长会先让顾客在门口取号排队,控制同时进店的人流;如果招牌原料用完,就推荐顾客换成柠檬水;真到了后厨快撑不住的时候,干脆拉下闸门“暂停接单十分钟”,让队伍散一散、后厨缓一缓。限流、降级、熔断,就是互联网系统面对汹涌请求时的三套管理大招。而限流最经典的两件武器,是两只“桶”:漏桶和令牌桶。漏桶像后厨门口匀速转动的传送带,不管前面排多少人,送进后厨的单子速度永远恒定;令牌桶像取号机,机器每秒吐固定数量的“制作券”,没人领就攒起来,高峰期顾客可以一次性掏出厚厚一叠券,让后厨短时间猛冲一波。这两个思路看似简单,背后却藏着高并发架构的生存智慧。今天,我们就从一杯奶茶讲起,把这两只桶彻底看透。

岗位关联

对 AI 从业者而言,限流算法是分布式系统与高并发设计的必修课。理解漏桶与令牌桶的差异,你才能在生产环境中设计出既抗得住突刺流量、又不会拖垮下游服务的可靠系统,也是面试大厂架构岗的高频考点。

目录
  1. 可视化演示
  2. 限流概念定义
  3. 漏桶算法原理
  4. 令牌桶算法原理
  5. 算法对比选型
  6. 降级熔断机制
  7. 工程实践优化
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示令牌桶以恒定速率填充令牌并允许突发流量,漏桶以恒定速率流出并平滑流量,以及两种算法在突发容忍与平滑性上的对比。

本节配有交互动效(进入视口后自动加载,约 3KB)。

令牌桶 速率r填充+容量b b=r*burst 请求需取令牌,允许一定程度的突发流量。

限流概念定义

周末午后,奶茶店门前瞬间涌来一大群刚逛完街的顾客。如果让他们全部涌进店里,柜台前会挤成一团,后厨的出单速度却还是那么慢——队伍只会越排越长,最后连店门口都被堵死。店长知道,问题的根源不是顾客太多,而是进店的速率超出了后厨的处理能力。于是他在门口装了一个旋转闸机,每分钟只放固定数量的人进店,进不去的顾客在门外排队等候。这个闸机,就是系统世界的“限流器”。

在分布式系统里,请求就像顾客,后端服务就像后厨。每个服务都有自己处理能力的上限,也就是系统容量——单位时间内最多能处理的请求数。当流入的请求速率超过这个上限,请求就会在服务端堆积成队列,队列过长会耗尽内存,进而引发雪崩:一个服务慢了,依赖它的上游跟着排队,一层层传导,整个链路全部瘫痪。限流的目标,就是让输入速率始终不超过服务能力,把过载扼杀在入口处。

衡量系统是否过载,有一个经典的指标叫利用率,它表达了“来的速度”和“做得完的速度”之间的关系:

所以,限流器的本质就是一扇“门”,它按照系统容量预先设定好放行速率,把不稳定的到来流量修剪成稳定的处理负荷。就像奶茶店的旋转闸机把汹涌的人潮拧成一列有序的队伍,限流让后端服务永远只面对自己吃得消的请求量。

ρ=λμ\displaystyle \rho = \dfrac{\lambda}{\mu}
当利用率 ρ 大于 1 时,请求进来的速度比处理速度快,系统必然排队积压,最终崩溃;小于 1 才能保持稳定。
  1. 到达速率 λ单位时间内新到系统的请求数量,相当于每秒涌到奶茶店门口的顾客数。
    λ\lambda
  2. 服务速率 μ单位时间内系统能处理完的请求数量,相当于后厨每秒能做出的奶茶杯数。
    μ\mu
  3. 利用率 ρ到达速率与服务速率的比值,ρ 越接近 1 越危险,超过 1 就是排队膨胀的开始。
    ρ=λμ\rho = \dfrac{\lambda}{\mu}

漏桶算法原理

店长装上闸机后发现一个问题:顾客的消费习惯很“脉冲”。电影散场时突然涌来 50 人,而后厨闲的时候一单都没有。如果只是简单限行,后厨还是会被突如其来的大单冲个措手不及。于是店长在后厨门口加了一条匀速传送带——不管前面队伍排多长,传送带每秒只把固定数量的订单单送进后厨,多出来的订单在传送带入口排队等待,排不下的顾客只能先离开。

这个“匀速传送带”,就是漏桶算法。漏桶把请求先放进一个桶(队列)里,桶的底部有一个固定大小的“漏口”,请求以恒定速率 r 从桶底漏出,交给后端处理。桶的容量决定了可以积压多少请求;一旦桶满了,新来的请求直接被丢弃——就像传送带入口排不下的顾客被礼貌请走。

漏桶算法可以用两个条件刻画:

漏桶最迷人的地方在于突发整流:再汹涌的流量进入桶里,出去时都被抹平成一条匀速直线。它特别适合保护那些“受不了突刺”的脆弱下游——比如数据库、第三方支付接口。但代价是,即使后厨此刻完全空闲,传送带也绝不会多送一单进去,空闲产能被白白浪费了。

Rout=r,Qwait≤Cbucket\displaystyle R_{out} = r,\qquad Q_{wait} \leq C_{bucket}
漏桶的输出速率 R_out 永远恒定等于 r,等待队列 Q_wait 不能超过桶容量 C_bucket,否则新请求溢出丢弃。
  1. 固定输出速率 r无论流入速率忽高忽低,漏桶每秒只漏出 r 个请求,这是它的灵魂约束。
    Rout=rR_{out} = r
  2. 等待队列 Q未被处理的请求先进先出地排在桶里,等待被漏出,体现“先进先出”的公平性。
    QwaitQ_{wait}
  3. 溢出条件队列长度达到桶容量上限后,新请求不再入队而是直接拒绝,防止无界积压。
    Qwait≤CbucketQ_{wait} \leq C_{bucket}

令牌桶算法原理

传送带方案虽然稳,但店长心疼浪费掉的空闲时间:凌晨没人的时候传送带空转,后厨闲着,等到下午高峰,所有订单却要先排队才能慢慢进后厨,很多顾客等不及就走了。于是店长换了个思路——取号机。取号机每秒吐出固定数量的“制作券”,没人领就攒成一叠放在机器里。顾客拿到券就能直接下单,后厨按券号依次制作。高峰期前攒下的一大叠券,可以让后厨在短时间内火力全开猛做一波。

这就是令牌桶算法。系统以固定速率 r 向桶中生成令牌,桶最多存储 b 个令牌。每个请求必须先获取一个令牌才能被放行,处理完后令牌被消耗。关键区别在于:令牌可以在低峰期累积,所以当突发流量来临时,系统可以一次性消耗桶里积攒的全部令牌,允许短时间内的请求速率超过 r,实现突发容忍。

令牌桶的动态过程可以用递推公式表达,它描述了每个时刻桶里剩多少令牌:

令牌桶算法巧妙地在“平滑”和“效率”之间找到了平衡:长期看,它的平均速率被令牌生成速率 r 锁死;短期看,它允许用攒下的令牌去承接突发流量。就像取号机在凌晨悄悄积攒制作券,到了下午高峰让后厨可以痛快地猛做一波,既保护了系统又没浪费产能。

B(t)=min⁡(b,  B(t−Δt)+r×Δt−Δn)\displaystyle B(t) = \min\left(b,\; B(t-\Delta t) + r \times \Delta t - \Delta n\right)
当前令牌数 = 上一时刻令牌数 + 新生成的令牌 − 被请求消耗的令牌,但总令牌数最多不超过桶容量 b。
  1. 上一时刻令牌数上次计算后桶里剩余的令牌数,是递推的基础。
    B(t−Δt)B(t-\Delta t)
  2. 新生成令牌令牌生成速率 r 乘以时间差 Δt,得到这段时间内新攒下的令牌。
    r×Δtr \times \Delta t
  3. 消耗令牌 Δn这段时间内被请求取走的令牌数量,每个请求消耗恰好 1 个。
    Δn\Delta n
  4. 容量封顶中间结果超过桶容量时取最小值 b,多生成的令牌直接丢弃,防止无限积攒。
    min⁡(b,  B(t−Δt)+r×Δt−Δn)\min\left(b,\; B(t-\Delta t) + r \times \Delta t - \Delta n\right)

算法对比选型

传送带和取号机,到底哪个更适合奶茶店?店长发现,这取决于顾客的脾气和店里的短板。如果短板是后厨怕被大单冲垮,那就用传送带(漏桶),把一切流量都磨平;如果短板是高峰时顾客流失,想尽量多接单,那就用取号机(令牌桶),在能力范围内尽力冲一冲。

从算法角度看,两者的本质差异在于如何处理突发流量:

选型贵在匹配场景。漏桶适合流量整形:下游是数据库写入、短信发送这类“速率一高就出事”的服务,必须把流量抹得平平整整;令牌桶适合接口限流:比如 API 网关、秒杀系统,业务希望服务在空闲时蓄力、高峰时多扛一些请求。业界常用的 Guava RateLimiter 本质就是令牌桶的改进版,因为它更符合“允许短时突刺”的互联网业务直觉。

Δnmaxleaky=0,Δnmaxtoken=b\displaystyle \Delta n_{max}^{leaky} = 0,\qquad \Delta n_{max}^{token} = b
漏桶任意时刻的瞬时突发放行量为 0;令牌桶在桶满的情况下,可以一次性放行 b 个请求。
  1. 漏桶突发放行输出速率恒定,任何瞬间都多放不出一个请求,突发量恒为 0。
    Δnmaxleaky=0\Delta n_{max}^{leaky} = 0
  2. 令牌桶突发放行桶满时积攒了 b 个令牌,可一次性放行 b 个请求,短时速率可达 r + b/Δt。
    Δnmaxtoken=b\Delta n_{max}^{token} = b
  3. 长期平均速率把时间轴拉长,两者的平均放行速率都收敛到令牌生成速率 r,区别只在“瞬间”。
    lim⁡T→∞N(T)T=r\lim_{T \to \infty} \dfrac{N(T)}{T} = r

降级熔断机制

再好的限流也有失守的时候。某天大促,客流远超预期,取号机吐券的速度已经拉满,可后厨还是跟不上。眼看队列越排越长,店长果断拉下总闸,挂出“暂停接单”的牌子——这就是熔断:当系统判断自己快撑不住时,直接拒绝所有新请求,快速失败,避免彻底崩溃。与此同时,店员开始向等不住的顾客推荐:“招牌珍珠没了,柠檬水马上好!”——这就是降级:返回一个简化但可用的兜底结果,而不是把顾客晾在那里。

熔断机制的运行像一个带保险丝的电路开关,有关闭、开启、半开三种状态。系统持续统计请求的错误率:

熔断和限流是两道不同的防线:限流在自己这一侧控制“我能接多少”,熔断在调用侧控制“下游还值不值得我打过去”。降级则是最后的兜底预案——缓存兜底、默认值兜底、简化逻辑兜底,保证用户体验的下限。三者配合,才能构成一套完整的保护机制。

E=FreqNreq,E>T⇒open\displaystyle E = \dfrac{F_{req}}{N_{req}},\qquad E > T \Rightarrow \text{open}
当一段时间内的错误率 E 超过阈值 T,熔断器从关闭跳到开启,开启期间所有请求快速失败;经过恢复时间后进入半开状态,放少量试探请求验证下游是否康复。
  1. 错误请求数统计窗口内超时、5xx 等失败请求的数量,代表下游服务正在“生病”。
    FreqF_{req}
  2. 总请求数同一统计窗口内发出的全部请求数量,作为错误率的分母。
    NreqN_{req}
  3. 错误率 E失败请求占比,直观反映下游服务的健康程度。
    E=FreqNreqE = \dfrac{F_{req}}{N_{req}}
  4. 阈值触发错误率超过设定阈值 T 时切换为 open(开启),不给下游继续施压。
    E>T⇒openE > T \Rightarrow \text{open}

工程实践优化

当奶茶店开成连锁品牌,每一家分店都要面对不同的客流量。总店的做法是:给每家分店装上统一的客流监测系统,根据历史数据调整闸机放行速度,一旦某家店排队过长,总店立刻调度隔壁门店支援。这就是限流从“算法”走向“工程”的过程——分布式限流。

在生产实践中,限流不只是写一个漏桶类那么简单。第一,分布式限流:在高并发集群中,多个服务实例共享同一个限流配额,通常借助 Redis 等中间件实现原子计数,或者在 API 网关层做统一限流,避免“每个实例限 100,整体却被打了 1000”的尴尬。第二,参数调优:限流的两个核心参数——速率 r 和桶容量 b,不能拍脑袋定,要通过压测确定系统的真实容量。工程上常用一个小公式估算容量:

第三,监控告警:限流不能“一限了之”。被拒绝的请求量、排队长度、熔断器状态都要实时上报;一旦拒绝率异常升高,说明限流参数需要动态调整。整套体系就像连锁店的总控台——分布式的闸机、经过压测的放行速率、实时的客流大屏,让每一家“分店”都在安全边界内优雅地运转。

QPS=CconcTavg\displaystyle QPS = \dfrac{C_{conc}}{T_{avg}}
通过压测工具测出系统能承受的最大并发数 C 和平均响应时间 T 后,两者相除即为单实例的 QPS 上限,再乘以实例数得到集群总限流阈值。
  1. 并发数 C压测时同时打向系统的请求连接数,是系统能扛住的“同时在场人数”。
    CconcC_{conc}
  2. 平均响应时间请求从发出到收到响应的平均耗时,反映后厨做一杯奶茶的速度。
    TavgT_{avg}
  3. 单机 QPS并发数除以平均响应时间,就是这台机器每秒能处理的请求量。
    QPS=CconcTavgQPS = \dfrac{C_{conc}}{T_{avg}}

AI 应用场景

电商大促秒杀流量治理

阶段:高并发架构设计

解决的问题:秒杀开始时,瞬间涌入的流量通常是平时的几十倍。如果全部放行到订单服务和数据库,数据库连接池会被打满,整个交易链路崩溃。传统做法靠临时加机器,成本高且扩容速度赶不上流量暴增。

具体案例:某电商平台在秒杀入口采用令牌桶限流,系统预热阶段令牌桶自动蓄满,秒杀开启瞬间允许一波突发流量进入;同时在下游支付回调处部署漏桶,将支付确认请求整形为恒定速率,避免支付网关被冲垮;当错误率超过阈值时熔断器自动开启,快速失败并降级返回“稍后重试”的提示页。

微服务网关统一限流

阶段:服务治理与网关设计

解决的问题:微服务架构中,某个下游服务的容量突然下降(如依赖的数据库故障),如果上游服务继续全量调用,故障会迅速扩散。传统做法是每个服务各自为政,缺乏统一管控。

具体案例:API 网关为每个下游服务配置独立的令牌桶,每个实例按配额放行;网关实时统计错误率,当某下游错误率超过 15% 时自动熔断 30 秒,期间返回缓存响应(降级),半开状态放 10% 试探流量验证恢复。该方案让故障被隔离在单一下游,整体可用性从 99.9% 提升到 99.99%。

大模型 API 调用配额管理

阶段:AI 应用编排与资源管控

解决的问题:大模型 API 的推理成本高、单实例并发能力有限。调用方如果并发失控,不仅拖垮模型服务,还会产生巨额费用。传统做法是硬性限制并发数,但高峰时大量请求被粗暴拒绝,体验差。

具体案例:某 AI 应用平台为每个租户分配独立的令牌桶配额(如每分钟 1200 个令牌),允许租户闲置时积攒令牌、推广活动时短时突发;同时对模型推理集群部署熔断器,当 GPU 服务延迟超过 5 秒时开启熔断,降级返回“排队中”并自动将请求切换到备用模型。这套方案让 GPU 利用率提升 40%,租户投诉率下降 60%。

Python 演示

python63 行
import time  class LeakyBucket:    """漏桶: 无论流入多快, 流出速率恒定。"""    def __init__(self, capacity, rate):        self.capacity = capacity        self.rate = rate        self.water = 0.0        self._last = time.time()     def _drip(self):        now = time.time()        self.water = max(0.0, self.water - (now - self._last) * self.rate)        self._last = now     def allow(self):        self._drip()        if self.water + 1 <= self.capacity:            self.water += 1            return True        return False  class TokenBucket:    """令牌桶: 令牌按速率补充, 桶内可积累, 允许突发。"""    def __init__(self, capacity, rate):        self.capacity = capacity        self.rate = rate        self.tokens = capacity        self._last = time.time()     def _refill(self):        now = time.time()        self.tokens = min(self.capacity, self.tokens + (now - self._last) * self.rate)        self._last = now     def allow(self):        self._refill()        if self.tokens >= 1:            self.tokens -= 1            return True        return False  def simulate(bucket, requests, interval):    passed = 0    for req in requests:        if req and bucket.allow():            passed += 1        time.sleep(interval)    return passed  if __name__ == '__main__':    leaky = LeakyBucket(capacity=5, rate=5)    token = TokenBucket(capacity=10, rate=5)     time.sleep(1)  # 低峰期: 令牌桶攒满, 漏桶排空     burst = [True] * 10  # 模拟瞬间涌入10个请求    print('漏桶通过:', simulate(leaky, burst, 0.02))    print('令牌桶通过:', simulate(token, burst, 0.02))
目的:模拟同一波突发流量经过漏桶和令牌桶后的放行数量差异,直观展示“漏桶恒定平滑、令牌桶允许突发”的特性。
  1. self.water = max(0.0, self.water - (now - self._last) * self.rate)按真实时间差计算漏出的水量,模拟漏桶持续排水。
  2. if self.water + 1 <= self.capacity:桶内水量加当前请求不超过容量才放行,否则拒绝。
  3. self.tokens = min(self.capacity, self.tokens + (now - self._last) * self.rate)令牌按速率补充,但总量封顶在桶容量。
  4. if self.tokens >= 1:有令牌才能放行,放行后消耗一个令牌。
  5. time.sleep(1)模拟低峰期,让令牌桶从空状态慢慢攒满令牌。
  6. burst = [True] * 10构造 10 个瞬间到达的突发请求,验证两种桶的应对差异。

常见误区

误区我刚学令牌桶时,觉得它既然能攒令牌、能爆发,那我们是不是可以把限流速率调得很高,让系统随意冲?反正有令牌就能过,突发多大都没问题。

正解令牌桶的突发能力被桶容量 b 严格限制。桶最多攒 b 个令牌,意味着一次能消耗的令牌最多只有 b 个,突发窗口一过,后续请求必须等待新令牌按速率 r 生成。这就好比取号机面前排了 100 人,但机器里只有 10 张券——最多只有 10 个人能立刻下单,剩下 90 人依然要等。

为何常见:大家只记住了“令牌可以积累、允许突发”这个亮点,却忽略了容量封顶的约束,把“允许短期突发”误听成“允许无限突发”。

误区漏桶输出恒定、平滑漂亮,看起来比令牌桶“有纪律”,那我是不是所有场景都用漏桶就最安全?

正解两种算法没有绝对优劣,只有适不适合。漏桶的平滑是以牺牲空闲产能为代价的——后厨闲着它也不会多送单;令牌桶允许突发,适合互联网业务“闲时蓄力、忙时爆发”的真实节奏。选型要看下游最怕什么:怕突刺选漏桶,怕浪费选令牌桶。

为何常见:初学时容易用“好坏”二元论理解算法,而工程选型本质是权衡取舍,离开业务场景谈算法优劣没有意义。

误区我听说限流不就是把请求拦住吗?熔断也是把请求拦住,那两者是不是一回事?系统限流做好就行了。

正解限流管的是“我这个服务能接多少”,熔断管的是“下游还值不值得调”。限流是自我保护,熔断是保护下游、避免故障扩散。奶茶店限流是控制门口进店人数,熔断是后厨快崩时拉闸停业——两套机制保护的对象和触发条件完全不同。

为何常见:两者的表象都是“拒绝请求”,初学者容易只看到动作的相似,忽略触发原因和保护目标的差异。

误区既然容量大能攒更多令牌、接更多突发流量,那把 b 从 100 调到 100000 不是更好吗?系统越能“扛”越厉害。

正解桶容量越大,单次突发放行的量就越大,后端瞬间承受的压力峰值也越高。如果容量远超后端真实处理能力,突发瞬间会把下游直接打爆,限流形同虚设。参数调优应该基于压测得出的真实容量,让 b 匹配“后端在几秒内能扛住的积压量”,而不是盲目贪大。

为何常见:“容量大 = 能力强”的直觉在限流场景下不成立,因为限流的目的是保护而非榨干系统,突发越猛,风险越大。

面试题

Q1. 漏桶算法最核心的特点是什么?

单选题 · easy

  • A.输出速率完全恒定平滑← 正确答案
  • B.输入速率完全恒定平滑
  • C.允许任意规模的突发
  • D.自动丢弃所有排队请求

答案:A。漏桶的灵魂是输出速率恒定——不管流入多猛,漏出的速率永远是固定的 r,就像匀速传送带。B 错在输入速率是不可控的,C 恰好是漏桶反对的,D 描述的是队列满溢时的丢弃策略而非核心特点。

Q2. 令牌桶算法允许突发流量的根本原因是?

单选题 · easy

  • A.桶容量无限可以随意扩张
  • B.令牌可以预先积累在桶中← 正确答案
  • C.请求可以无限排队等待
  • D.令牌生成速率可以动态改变

答案:B。令牌桶允许突发,是因为低峰期生成的令牌没被消耗,可以攒在桶里,高峰时一次性消耗这些令牌。A 错在桶容量有限,C 错在令牌桶不负责无限排队,D 错在令牌生成速率是固定配置而非动态变化。

Q3. 漏桶算法的输出速率由什么决定?

单选题 · mid

  • A.请求的到达速率决定
  • B.桶容量的大小决定
  • C.固定的漏水速率决定← 正确答案
  • D.排队等待的时间决定

答案:C。漏桶的输出速率只由“漏水速率”这一个参数决定,与到达速率、排队时间无关。桶容量只影响能积压多少请求,不影响输出速率。这就像传送带的速度由电机决定,跟前面排多少人没关系。

Q4. 令牌桶桶已满时新生成的令牌会怎样?

单选题 · mid

  • A.继续累积不会浪费
  • B.直接丢弃新令牌← 正确答案
  • C.扩容桶容量存储
  • D.转存到备份队列

答案:B。令牌桶有容量上限 b,桶满后新生成的令牌被直接丢弃。这保证了令牌不会无限积累,从而限制了最大突发量。A 错在违背容量约束,C 和 D 都不是令牌桶的机制。

Q5. 熔断器开启后的直接结果是?

单选题 · mid

  • A.限速处理所有请求
  • B.快速失败拒绝请求← 正确答案
  • C.排队等待恢复服务
  • D.尽最大努力重试

答案:B。熔断器开启后,所有进入的请求直接快速失败,不再调用下游,避免给已故障的下游继续施压。A 是限流的行为,C 可能加重积压,D 会加剧故障扩散。就像奶茶店拉闸后不再接单,而不是让顾客排队等。

Q6. 服务降级最常见的兜底手段是?

单选题 · easy

  • A.返回缓存或默认值← 正确答案
  • B.直接抛出系统异常
  • C.无限等待重试成功
  • D.重启所有下游服务

答案:A。降级是用一个简化但可用的结果替代真实结果,最常见的就是返回缓存数据或预设默认值,保证用户拿到的不是报错。B 会破坏体验,C 会导致请求长时间挂起,D 是运维操作而非降级策略。

Q7. 某系统令牌桶容量为 10,令牌生成速率为每秒 5 个,系统空闲 10 秒后瞬间涌入 20 个请求,最多能通过多少个?

单选题 · hard

  • A.约 10 个请求← 正确答案
  • B.约 15 个请求
  • C.约 20 个请求
  • D.全部 20 个请求

答案:A。系统空闲 10 秒,理论上生成了 50 个令牌,但桶容量只有 10,所以桶里最多攒 10 个令牌。瞬间涌入 20 个请求时,前 10 个消耗掉全部令牌得以通过,后 10 个因桶已空且请求是“瞬间”到达、来不及补充新令牌而被拒绝。因此最多通过 10 个。

Q8. 令牌桶限流需要配置的核心参数有哪些?

多选题 · mid

  • A.令牌生成速率← 正确答案
  • B.桶的最大容量← 正确答案
  • C.请求超时时间
  • D.网络带宽大小

答案:AB。令牌桶只有两个核心参数:令牌生成速率 r(决定长期平均速率)和桶容量 b(决定允许的突发上限)。请求超时是超时控制模块的事,网络带宽是网络层指标,都不是令牌桶的配置项。

Q9. 高并发系统中限流常见的工程落地方式有?

多选题 · mid

  • A.网关层统一限流← 正确答案
  • B.Redis 分布式计数← 正确答案
  • C.客户端本地限流← 正确答案
  • D.数据库加全局锁

答案:ABC。网关限流作为统一入口,Redis 原子计数实现跨实例的分布式限流,客户端本地限流做前置保护,这三者都是常见方案。D 用数据库全局锁限流会严重拖垮数据库性能,属于典型反模式。

Q10. 关于漏桶与令牌桶的对比,正确的说法有哪些?

多选题 · hard

  • A.漏桶输出更加平滑← 正确答案
  • B.令牌桶容忍短时突发← 正确答案
  • C.漏桶会丢弃溢出请求← 正确答案
  • D.两者性能完全相同

答案:ABC。漏桶把任意流量整形为恒定速率,平滑性最强;令牌桶通过攒令牌容忍短时突发,突发量被桶容量限制;漏桶队列满时新请求被丢弃,三者均正确。D 错在两者实现机制不同,性能特征也不同,说“完全相同”过于绝对。