我需要了解在REST中处理异步操作的方法以及它们的优点和缺点。我发现了一些方法:
基于资源:将操作状态建模为状态。用户进行异步REST调用(PUT,POST等)获取Accepted
或In-Progress
响应(202
)。此外,通过GET重复轮询状态URI,以检查来自操作执行的状态/进度/消息。
问题:此资源在服务器上应该有多长时间处于活动状态?如果客户端在操作完成之间的大间隔轮询中,我们如何返回状态?似乎坚持执行状态会起作用。但是,存档/删除的时间有多长,这种标准方法是什么?
基于回调:需要异步请求才能拥有回调URI。异步处理请求,完成后调用带有操作状态/结果的回调URI。
问题:这似乎更优雅,服务器端的开销更少。但是如何处理回调服务器间歇性关闭,没有响应等情况?实现回调URI提供重试配置的典型重试?这种方法还有其他缺点吗?
Servlet 3.0异步支持: HTTP客户端与Java Servlet建立连接的位置,该Java Servlet在显式关闭之前保持打开状态,直到关闭的客户端和服务器可以通过它进行异步通信。
问题:自从它的Servlet 3.0规范以来,我认为Jersey,即Spring REST实现,目前尚未采用这种方法。是否有任何特定的REST实现,它使用类似的方法或指针来实现这一点?
任何其他方法,也许是商业方法?
答案 0 :(得分:6)
Spring 3.2+支持Servlet 3.0的异步功能。来自Spring Blog:
您可以通过将任何现有控制器方法更改为返回Callable来使其异步。例如,返回视图名称的控制器方法可以返回Callable。返回名为Person的对象的@ResponseBody可以返回Callable。对于任何其他控制器返回值类型也是如此。
Jersey 2+还支持异步服务器。请参阅参考文档中的Asynchronous Services and Clients章节。
答案 1 :(得分:3)
我认为,这种方法取决于初始请求和操作结束之间的时间差。
答案 2 :(得分:0)
我正在处理相同的情况,并找到了使用Location
标头响应来提供可监控的资源以检查状态(通过轮询当然)的常用方法。这似乎是最好的,但在我的情况下,我没有创建资源,所以我没有位置来检查状态(我的异步过程只是构建一个缓存页面)。
您始终可以使用自己的标题来估算完成操作的时间。无论如何,我正在考虑使用Retry-After
标题来估计时间。你们觉得怎么样?
答案 3 :(得分:0)
我知道这已经过时了,但我想我会在这里说,如果你想要的是可以在无状态环境中扩展的东西,那么你应该选择第一个选项。您可以在任何地方执行基础操作,如果您将结果放在像redis这样的内容中,则客户端进行后续轮询请求的Web服务器无关紧要。我通常会将轮询间隔放在我发送给客户端的响应中。当结果准备就绪时,我将向客户端返回一个SEE OTHER,其中包含URI中结果的id。