14

我需要了解在 REST 中处理异步操作的方法以及它们的优缺点是什么。我发现的一些方法:

  1. 基于资源:将操作的状态建模为状态。用户进行异步 REST 调用(PUT、POST 等)获取AcceptedIn-Progress响应(202)。此外,通过 GET 反复轮询状态 URI,以检查来自操作执行的状态/进度/消息。

    问题:该资源在服务器上应该活动多长时间?如果客户端在操作完成之间的大间隔轮询,我们如何返回状态?似乎坚持执行状态会起作用。但是坚持多久,什么时候存档/删除,是这种标准的做法吗?

  2. 基于回调:异步请求需要有回调 URI。请求被异步处理,并在完成后使用操作状态/结果调用回调 URI。

    问题:这似乎更优雅,并且在服务器端涉及更少的开销。但是如何处理回调服务器间歇性宕机、无响应等场景呢?在回调 URI 也提供重试配置的情况下实现典型的重试?这种方法还有其他缺点吗?

  3. Servlet 3.0 异步支持: HTTP 客户端与 Java Servlet 建立连接,Java Servlet 一直保持打开状态,直到它被显式关闭,并且在关闭之前,客户端和服务器可以通过它进行异步通信。

    问:自从它的 Servlet 3.0 规范以来,我认为 Spring REST 实现 Jersey 目前还没有使用这种方法。是否有任何特定的 REST 实现使用类似的方法或指针来使其成为可能?

  4. 还有其他方法,也许是商业方法?

4

4 回答 4

6

Spring 3.2+ 支持 Servlet 3.0 的异步特性。来自春季博客

您可以通过将任何现有控制器方法更改为返回 Callable 来使任何现有控制器方法异步。例如,返回视图名称的控制器方法可以返回 Callable。返回一个名为 Person 的对象的 @ResponseBody 可以改为返回 Callable。任何其他控制器返回值类型也是如此。

Jersey 2+ 还支持异步服务器。请参阅参考文档中的异步服务和客户端章节。

于 2013-10-01T11:46:01.633 回答
3

我认为,该方法取决于初始请求和操作结束之间的时间间隔。

  • 对于短时间操作(< 10s),我只会保持请求打开并在操作完成后返回响应;
  • 对于长操作(< 30m),我会使用 servlet 3.0 或 Comet 模型;
  • 对于极长的操作(几小时,几天)来说,对我来说,这只是基于客户端的轮询或具有大超时的 Comet。
于 2013-04-25T13:13:13.523 回答
0

我知道这已经过时了,但我想我会在这里插话说,如果你想要的是可以在无状态环境中扩展的东西,那么你应该选择你的第一个选择。您可以在任何地方执行底层操作,如果您将结果放入 redis 之类的东西中,则客户端发出后续轮询请求的 Web 服务器无关紧要。我通常会将轮询间隔放在发送给客户端的响应中。当结果准备好时,我将向客户端返回一个 SEE OTHER,其中包括 URI 中结果的 id。

于 2013-11-27T16:00:15.047 回答
0

我现在正在处理相同的情况,并找到了使用Location标头响应提供可以监视以检查状态的资源的常用方法(当然是通过轮询)。这似乎是最好的,但就我而言,我没有创建资源,所以我没有检查状态的位置(我的异步过程只是为了构建一个缓存页面)。

您始终可以使用自己的标题来给出完成操作的估计时间。无论如何,我正在考虑使用Retry-After标题来给出估计时间。你们有什么感想?

于 2013-10-01T11:24:51.427 回答