我仍然记得那个夜晚——我们的API在突如其来的流量峰值下开始“窒息”。用户接二连三收到429状态码,支持群里的Slack消息刷到飞起,而我感觉自己就像一个拿着牙签试图抵挡一整群暴风兵的人。当时我们的方案很简单:固定窗口计数器。每分钟重置一次计数,一旦达到阈值就直接拒绝请求。在测试环境里一切正常,可真实流量一来,用户的“突发性”让窗口在最糟糕的瞬间猛然关闭——合法请求被误伤,而少数恶意客户端却能从缝隙中溜过去。
那一刻我才明白:限流器不仅仅是在“计数”,它的本质是“平滑”。我们需要的机制是既能吸收短时突刺,又能在更长的时间跨度上保护后端。于是,寻找更好限流算法的征程开始了。
![]()
转机出现在我重新审视经典的令牌桶算法。你可以把它想象成一个不断以稳定速率注水的小蓄水池,每个请求会从池中取走一个令牌;如果池子干了,请求就必须等待或者被拒绝。而巧妙之处在于,这个池子有一个最大容量——允许突发流量暂时占满整个池子,同时注水速率又保证了长期的平均最大吞吐。这样一来,短期爆发被“吞掉”,长期速率又被严格限制。
为什么它比固定窗口更优秀?首先,没有“悬崖边缘”。固定窗口在边界处会突然重置,导致窗口末尾与新窗口开头可能形成双重突发,而令牌桶是连续补充令牌的,天然抹平了这种边界效应。其次,它极其简单:只需要两个状态变量——当前令牌数和上次补充时间戳,在许多场景下甚至能做到无锁。最后,它的行为完全可以预测:数学上能保证在任意长度为 t 的时间间隔内,允许通过的请求数不超过 rate * t + burst。
直到今天,我每次把令牌桶想象成一把光剑手柄时,还是会有那种“啊哈”的顿悟感——它稳定、可靠,随时准备弹开任何迎面而来的爆能束。如果你也在为限流器的选择头疼,不妨试试用令牌桶取代固定窗口,让那场“429风暴”真正成为过去。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.