专业书籍精读 · System Design Interview 卷一 · 第 4 章

设计限流器

System Design Interview: An Insider's Guide · Vol 1 · Ch 4 · Alex Xu · 2020

EN →

这一章讲什么?

网上很多服务都会给你一个「用量上限」:这个软件的免费版一天只让你转 5 次文件,那个网站不让你一分钟连发二十条评论。这一章讲的就是这个上限背后的那个小零件——限流器:一个坐在大门口的检票员,规定「每人每分钟最多进几次」,超了就把人拦在门外。

先说个怪事

你大概以为这道门是用来防坏人的。其实它拦下来的,多半是好人。更准确地说,是好人写错的一段程序——某个客户的软件里有个循环忘了停,一秒钟朝你发几千次请求;他自己不知道,也没恶意,可效果和攻击一模一样。限流器真正的日常工作,是不让一个人的失手,变成所有人的事故。

旧世界为什么难

没有这道门,一切按「先到先得」运转:谁喊得响谁被服务。听着公平,实际很残酷——一个失控的程序几秒内就能把服务的处理能力全部吃光,剩下成千上万个规规矩矩的用户,同时被挡在外面。还有一笔更直接的账:很多服务背后要调别人家的收费接口,按次算钱,一个转不停的循环一夜就能烧光一个月的预算。

核心机制:四种守门的姿势

① 发糖法(令牌桶)。门口摆一个碗,每秒往碗里放 2 颗糖,碗最多装 40 颗。想进门,先从碗里拿一颗;碗空了就进不去。妙处在于:你安静了一阵子,碗里就攒满了糖,这时候可以一口气进 40 个人——它容得下短时间的一阵猛冲,但拉长了看,平均还是每秒 2 个。

② 排队法(漏桶)。门口只放一条队,无论外面涌来多少人,里面永远每秒放 2 个进去,一个不多。好处是里面的节奏永远平稳;代价是队伍一旦被挤满,后来的人连队都排不上,直接被劝走。

③ 整点清零法(固定窗口)。门卫拿个计数器,每到整分钟清零,这一分钟数满 5 个就不放了。最省事,但有个漏洞:如果 5 个人在 0 分 55 秒挤进来,另外 5 个在 1 分 05 秒又进来,那么这中间的短短十几秒里,实际上进去了 10 个——是规定的两倍。

④ 往回看一分钟(滑动窗口)。把「这一分钟」改成「从现在往回数的一分钟」,整点漏洞就补上了。代价是门卫得记住每个人进门的时刻,人一多这本账就又厚又贵。折中办法是不记流水账,只把上一分钟的人数按重叠比例折算一部分进来——不完全准,但便宜得多。

该怎么选

想给用户留一点「偶尔手快」的余地,用发糖法;要求下游节奏绝对平稳,用排队法;只想快速上一个粗糙的挡板,整点清零法半小时就写完了。

诚实说一句代价:这道门自己也可能出问题——它坏了,是该把所有人都放进去,还是把所有人都挡在外面?这个问题没有标准答案,但每个上线限流的团队都必须先想清楚。

一句话记住

限流器是门口的检票员,防的主要不是坏人,是一个人的失手拖垮所有人。四种守门姿势:发糖(容得下突发)、排队(节奏平稳)、整点清零(省事但边界漏水)、往回看一分钟(准但贵)。选哪种,取决于你愿不愿意容忍突发。

想进到具体算法、量级和示意图? → 切到精读版