第 11 章 · 限流第 8 页,共 9 页
请求被拒绝时,对方会收到什么?
被拒绝的请求会带回状态码 429,常常还附着一句「多久以后再来」。守规矩的一方按提示等待,到点再发就会被放行。
为什么需要
被拒绝的一方需要知道两件事:被拒绝是因为自己发得太快,而不是百家菜出了故障;以及要等多久才能再来。不知道原因,程序可能以为服务器坏了,立刻换一种办法再试;不知道要等多久,它只能一次次试探,反而发出更多的请求。
怎样做
浏览器和 App 与网站交换请求和时,遵守一套叫 HTTP 的规则:每个响应开头都有一个三位数的,说明结果,比如 200 表示成功,404 表示找不到。限流器拒绝请求时返回(HTTP 429 Too Many Requests),意思是「你在一段时间里请求得太多了」,由互联网标准 RFC 6585 在 2012 年定义。它说的是这一个请求者超出了上限,服务器本身通常运转正常;503 才表示问题在服务器一侧:服务器因暂时过载或维护,眼下处理不了请求(RFC 9110,2022)。
429 的响应还可以附上(Retry-After),告诉对方至少等多少秒再来;很多服务还附上几项,写明上限、剩余和恢复的时刻。各家写法不同,统一写法的标准草案还在讨论中(制定互联网标准的 IETF,2026)。用浏览器看网页的读者看不到这些说明,网站要在页面上写一句,比如「请求过于频繁,请 7 秒后再试」。
在下图里,以智能厨具公司的程序的身份连续发请求。这里的限流器用第 2 页的固定窗口:每 12 秒最多 8 个;为了演示,「现在」从第 5 秒开始。被拒绝以后,看响应里写了什么,再按提示等待、重新发送。
被拒绝之后:按提示等待,再试一次
先看这里先看「最近一个响应」这张卡片:连按 9 次「发一个请求」,第 9 个被拒绝,响应里写着 429 和「7 秒后再来」;按「按提示等待」以后再发,请求被放行。
最近一个响应
还没有发出请求。
代价是什么
被拒绝的请求算不算进次数,各家不同;本章前面的图里都不算。不算的话,不停的一方只是白发了请求,配额一恢复照样放行;算的话,每重试一次都推迟了自己恢复的时刻,只要不停,就再也不会被放行。下面第二张图对照这两种算法,限流器换成第 3 页的「记下每一次的时间」:固定窗口一到交界就清零,算不算被拒绝的,到了下一个窗口都一样;记下每一次的时间不清零,差别才看得出来。YouTube 给开发者的配额连无效的请求也要扣(2026)。不管哪一种,最省事的都是按提示等待。
不停重试:被拒绝的请求算不算进次数
先看这里先看第 12 秒以后:被拒绝的请求「不计入」时,最早的记录移出往前 12 秒的范围,程序的请求又会被放行;「也计入」时,它一直在重试,记录总是满的,再也没有一个被放行。
- 放行 24 个
- 拒绝 12 个
已选:请求 1 · 第 0 秒 · 放行
用左右方向键选择一项。
被拒绝的不计入:每 12 秒仍有 8 个被放行,其余的请求白白发出。
429 只对守规矩的一方有用,抓取脚本和攻击程序不会因此停下;为每个超额的请求写响应也费力气,所以 RFC 6585 说,服务器遭受攻击时直接断开连接也可以。也并非人人都照标准用:网站服务器软件 NGINX 的限流功能默认返回 503,要另外设置才返回 429;代码网站 GitHub 超出上限时返回 429,或者返回表示「不允许你这样做」的 403,还提醒被限流后仍不停发请求的程序可能被封禁(文档均未注明日期)。
如果很多被拒绝的一方在同一刻一齐重试,会发生什么,第 12 章再讲。
资料来源
以下资料均于 2026-10-19 访问。