当客户端是多线程时,客户端对 HTTP 429 的正确反应是什么?

Har*_*ald 5 multithreading http rate-limiting http-status-code-429

HTTP 状态代码 429 告诉发出请求的客户端在响应的 Retry-After 标头中指定的时间段后退出并重试请求。

在单线程客户端中,很明显,获取 429 的线程应该按照指示等待,然后重试。但RFC明确指出

本规范没有定义源服务器如何识别用户,也没有定义它如何计算请求。

因此,在多线程客户端中,保守的方法会阻止所有线程发送请求,直到 Retry-After 时间点。但:

  • 许多线程可能已经超过了它们可以记录来自一个被拒绝线程的信息的程度,并且将至少再发送一个请求。
  • 线程之间的全局同步可能很难实现和正确
  • 如果设置不仅运行多个线程而且运行多个客户端,可能在不同的机器上,在一个 429 上回退所有这些变得非常重要。

有没有人有云提供商的服务器如何实际处理这个领域的具体数据?如果我不全局阻止所有线程,它们会立即恶化吗?微软的建议

  1. 等待 Retry-After 字段中指定的秒数。
  2. 重试请求。
  3. 如果请求再次失败并显示 429 错误代码,则您仍然受到限制。继续使用推荐的 Retry-After 延迟并重试请求,直到成功。

它两次说“请求”而不是“任何请求”或“所有请求”,但这是我不确定的法律类型解释。

为了确保这不是一个意见问题,让我尽可能以事实为基础来表述它:

是否有更详细的云 API 规范(微软、谷歌、Facebook、Twitter)然后上面的例子让我做出明智的决定是否需要全局回退或是否足以回退获得的特定请求429?

tgk*_*rog 1

服务器知道同步或期望程序员这样做是很困难的。因此,除非他们收到大量请求,并且在 429 之后根本不会退缩,否则怀疑是否会受到惩罚。

每个线程都应该等待,但在被单独告知后,每个线程都会等待。

一个好的系统会知道它的速率是多少并且在这个速率之内。实现这一点的一种方法是在请求之间使用 sleepFor 变量。可以通过反复试验得出精确的产品值,该值是睡眠时间减去先前的请求时间。

因此,如果一个请求结束,并说它花了 x 毫秒。现在,如果睡眠时间为 0 或更少,则立即移动到下一个请求,如果为 1 或大于找出 sleepTime - x,如果小于 1,则立即转到下一个,否则睡眠这么多毫秒,然后移动到下一个请求。

另一种方法是在请求 1 时设置 timeCountStarted;每5分钟左右计数一次。每次请求后,检查当前线程的实际请求数是否大于该数。如果是,则当前线程将休眠,直到 5 分钟结束,然后再转到下一个线程。这里可以配置5作为时间周期。如果请求后计数不超过设定数字,但自 timeCountStrarted 以来经过的时间超过 5 分钟;然后将 timeCountStrarted 设置为当前时间并将请求计数设置为 0。

我们所做的是将这些配置值保存在数据库中,但在运行时缓存它们。

还有一个使缓存无效的页面,因此如果我们愿意,我们可以从管理页面更新数据库,然后使缓存无效,从而客户端将在运行时获取新信息。这有助于配置正确的值以保持在 API 限制内并完成足够的工作。