【问题标题】:How to avoid polling for time-consuming async REST requests?如何避免轮询耗时的异步 REST 请求?
【发布时间】:2019-05-17 00:25:58
【问题描述】:

问题在于如何设计一个 REST Web 服务来执行耗时的工作(数量级为几秒和几分钟)。

最快的解决方案是如下进行:

  1. 客户端向服务器发送POST请求(POST /job),答案有 HTTP 状态 202 并将包含作业 ID;
  2. 客户端通过 GET 定期询问作业状态(例如 GET /job/:id/status);
  3. 当作业完成时,客户端使用 GET 请求结果(例如 GET /job/:id/result)。

我不喜欢第 2 步,因为有许多工作正在进行,服务器不必要地超载。 为了避免这种情况,我想到了另外两个解决方案:

  • 当客户端执行第一个 POST 请求时,它还会给出一个 URL,该 URL 可以 用作来自服务器的回调。当服务器结束 详细说明,它将通过 GET/POST 通知此 URL 的客户端 请求;
  • 服务器提供WebSocket,客户端可以在其中注册 并在工作完成时获得“通知”;

所有三个解决方案都有我不喜欢的方面:

  1. 轮询:服务器过载;
  2. 回调: 客户端必须为服务器提供一个 URL;
  3. websocket: 为什么要向 REST web 服务引入另一种“技术”? 也许,在这一点上,最好只使用 websockets 来做 所有请求。

还有其他解决方案吗?如果不是,您认为这三个中哪一个更可靠?

【问题讨论】:

  • 您始终可以选择对频繁轮询的客户端进行速率限制。您的建议还要求客户端也作为服务器工作,以便实际的服务器可以扮演客户端的角色。这在某种程度上违反了客户端-服务器范式。如果您需要持续的来回通信,我猜 REST 不是适合您的架构。
  • 好问题....

标签: rest asynchronous polling


【解决方案1】:

轮询往往很容易实现,而且非常可靠。可靠性来自于解决方案的简单性。一般来说,轮询请求应该是非常便宜的请求。通过降低轮询频率并一次检查多个作业(例如,在一个请求中发送 1000 个 ID),可以提高轮询效率。

任何非轮询解决方案都必须是一种主动通知形式。您提出的 HTTP 回调解决方案要求客户端运行 Web 服务器。可以,但好像没必要。

网络套接字的想法显然也很有效。您将需要重新连接逻辑并处理在客户端碰巧断开连接时作业完成的情况。客户端代码可能会涉及线程,因为您可能不希望每个作业有一个 Web 套接字连接。

比使用 Web 套接字更简单的想法是使用“comet”HTTP 请求。服务器保持 HTTP 请求打开,直到作业完成。这对于异步 IO 非常有效,因此在等待时不会阻塞任何线程。但如果连接被切断,则必须实施一些重新连接策略。

您可以让服务器将消息写入客户端读取的队列。

所有这些通知解决方案往往比简单的轮询解决方案复杂得多。他们需要更多的开发时间,并且会更频繁地中断生产。但是它们可以具有更低的延迟并使用更少的资源。我会尝试进行投票。很可能它会起作用,并且您很快就完成了。

【讨论】:

    【解决方案2】:

    您几乎自己回答了您的问题。问题是,您会根据自己的要求选择哪种方法。您的所有建议都是解决您的问题的方法,但您必须重视它们并自己决定。但是我认为您对方法 1 过于夸大了。如果您制定进度策略,例如不定期进行民意调查(而不是池),请说 30 秒后第一次民意调查,再过 20 秒后进行下一次民意调查,然后在 10 秒后,然后在 5 秒后,然后可能会重复该序列,那么服务器不会有那么大的压力。

    此外,如果您能以某种方式预测作业的复杂性,您选择的时间间隔可能基于 POST 请求的响应。因此,如果这项工作需要几分钟,例如,每 5 秒轮询一次是没有意义的。您可以制定一个类似数组的策略(时间以秒为单位):[300, 120, 60, 30, 20, 10],这意味着您将先等待 5 分钟,然后再等待 2 分钟,然后再等待 1 分钟,等等 - 你得到它,您可以以 10 秒的间隔完成。由于工作本身可能需要几分钟时间,因此我认为结果延迟几秒钟(即准备好,但未按时送达)并不重要。

    【讨论】:

    • 智能轮询应该可以提高效率,这可以作为一个起点。也感谢您在第一个 POST 答案中提供投票时间表的想法。 PS:感谢指出错字,我马上更正
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-04
    • 2020-03-14
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    相关资源
    最近更新 更多