5

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

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

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

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

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

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

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

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

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

是否有更详细的云 API 规范(Microsoft、Google、Facebook、Twitter)然后上面的示例允许我做出明智的决定,是否需要全局回退,或者是否足以回退得到的特定请求429?

4

1 回答 1

0

服务器知道同步或期望程序员这样做很重要。所以怀疑是否有惩罚,除非他们在 429 之后收到一大堆根本不退缩的请求。

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

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

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

另一种方法是每 5 分钟左右计数一次,然后如果线程的实际请求可能超过此值,则它会休眠直到 5 分钟结束,然后再进入下一个。这里5可以配置为timePeriod。

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

于 2019-05-12T18:47:49.277 回答