I need to understand what approaches there are to handle asynchronous operations in REST and what their advantages and disadvantages are. Some approaches I found:
我需要了解有哪些方法可以处理REST中的异步操作以及它们的优点和缺点。我找到的一些方法:
-
Resource Based: Where the status of an operation is modeled as a status. User makes an async REST call (PUT, POST etc.) gets
Accepted
orIn-Progress
response (202
). Further a status URI is polled repeatedly via GET to check status/progress/messages from operation execution.基于资源:将操作的状态建模为状态。用户进行异步REST调用(PUT,POST等)获得接受或正在进行响应(202)。此外,通过GET重复轮询状态URI以检查来自操作执行的状态/进度/消息。
Question: How long should this resource be active at Server? If the client polls in large intervals where in between the operation completes, how do we return the status? Seems like persisting the execution status would work. But how long to persist, when to archive/delete, is this kind of standard approach?
问题:此资源在Server上应该有多长时间处于活动状态?如果客户端在操作完成之间的大间隔轮询中,我们如何返回状态?似乎坚持执行状态会起作用。但是,存档/删除的时间有多长,这种标准方法是什么?
-
Callback Based: Where an async request is required to have a callback URI. The request gets processed asynchronously and upon completion makes a call to the callback URI with the operation status/result.
基于回调:需要异步请求才能拥有回调URI。异步处理请求,完成后调用带有操作状态/结果的回调URI。
Question: This seems more elegant and involving less overhead at the server side. But how to handle scenarios where the callback server is intermittently down, not responding, etc.? Implement a typical retries where the callback URI provides retries configuration as well? Is there any other downside to this approach?
问题:这似乎更优雅,服务器端的开销更少。但是如何处理回调服务器间歇性关闭,没有响应等情况呢?实现回调URI提供重试配置的典型重试?这种方法还有其他缺点吗?
-
Servlet 3.0 Asynchronous support: Where an HTTP client makes a connection to a Java Servlet, which remains open until it is explicitly closed and until closed client and server can communicate asynchronously over it.
Servlet 3.0异步支持:HTTP客户端与Java Servlet建立连接的位置,该Java Servlet在显式关闭之前保持打开状态,直到关闭的客户端和服务器可以通过它进行异步通信。
Question: Since its Servlet 3.0 spec, I think Jersey, the Spring REST implementation, doesn't utilize this approach as of now. Is there any specific REST implementation which utilizes a similar approach or pointer on ways to make it possible?
问题:自从它的Servlet 3.0规范以来,我认为Spring,Spring REST实现,目前还没有使用这种方法。是否有任何特定的REST实现,它使用类似的方法或指针来实现它的可能性?
-
Any other approaches, maybe commercial ones?
任何其他方法,也许是商业方法?
4 个解决方案
#1
5
Spring 3.2+ supports the async features of Servlet 3.0. From the Spring Blog:
Spring 3.2+支持Servlet 3.0的异步功能。来自Spring博客:
you can make any existing controller method asynchronous by changing it to return a Callable. For example a controller method that returns a view name, can return Callable instead. An @ResponseBody that returns an object called Person can return Callable instead. And the same is true for any other controller return value type.
您可以通过更改任何现有的控制器方法以使其返回Callable来使其异步。例如,返回视图名称的控制器方法可以返回Callable。返回名为Person的对象的@ResponseBody可以返回Callable。对于任何其他控制器返回值类型也是如此。
Jersey 2+ also supports asyncronous servers. See the Asynchronous Services and Clients chapter in the reference docs.
Jersey 2+还支持异步服务器。请参阅参考文档中的“异步服务和客户端”一章。
#2
3
I think, the approach depends on time gap between initial request and the end of operation.
我认为,这种方法取决于初始请求和操作结束之间的时间差。
- For short-time operations ( < 10s ) I would just keep the request open and return response when operation finished;
- For long operations ( < 30m ) I would use servlet 3.0 or Comet model;
- For extremely long operations ( hours, days ) good enough way, as for me, is just client-based polling or Comet with big timeouts.
对于短时间操作(<10s),我只是保持请求打开并在操作完成时返回响应;
对于长时间操作(<30m),我会使用servlet 3.0或Comet模型;
对于极长的操作(小时,天),对我而言,只是基于客户端的轮询或具有大超时的Comet。
#3
0
I'm dealing now with the same situation and found the common approach of using Location
header response to give a resource that can be monitored to check status (by polling of course). That seems to be the best, but in my case, I'm not creating a resource so I don't have a location to check the status (my async process is just to build a cache page).
我正在处理相同的情况,并找到了使用Location头响应的常用方法,以提供可以监视的资源来检查状态(通过轮询当然)。这似乎是最好的,但在我的情况下,我不是创建资源,所以我没有位置来检查状态(我的异步过程只是建立一个缓存页面)。
You can always use your own headers to give an estimated time to complete the operation. Anyway I'm thinking of using Retry-After
header to give an estimated time. What do you guys think?
您始终可以使用自己的标头来估计完成操作的时间。无论如何,我正在考虑使用Retry-After标头来估计时间。你们有什么感想?
#4
0
I know this is old but I thought I'd chime in here to say that if what you want is something that can scale out in a stateless environment then you should go with your first option. You can perform the underlying operation anywhere and if you put the result in something like redis it will not matter to what web server the client makes subsequent polling requests. I'll usually put the polling interval in the response I sent to the client. When there a result is ready I will return the client a SEE OTHER that includes the id of the result in the URI.
我知道这已经老了,但我想我会在这里说,如果你想要的是可以在无状态环境中扩展的东西,那么你应该选择第一个选项。您可以在任何地方执行基础操作,如果您将结果放在像redis这样的内容中,那么客户端进行后续轮询请求的Web服务器也无关紧要。我通常会将轮询间隔放在我发送给客户端的响应中。当结果准备就绪时,我将向客户端返回一个SEE OTHER,其中包含URI中结果的id。
#1
5
Spring 3.2+ supports the async features of Servlet 3.0. From the Spring Blog:
Spring 3.2+支持Servlet 3.0的异步功能。来自Spring博客:
you can make any existing controller method asynchronous by changing it to return a Callable. For example a controller method that returns a view name, can return Callable instead. An @ResponseBody that returns an object called Person can return Callable instead. And the same is true for any other controller return value type.
您可以通过更改任何现有的控制器方法以使其返回Callable来使其异步。例如,返回视图名称的控制器方法可以返回Callable。返回名为Person的对象的@ResponseBody可以返回Callable。对于任何其他控制器返回值类型也是如此。
Jersey 2+ also supports asyncronous servers. See the Asynchronous Services and Clients chapter in the reference docs.
Jersey 2+还支持异步服务器。请参阅参考文档中的“异步服务和客户端”一章。
#2
3
I think, the approach depends on time gap between initial request and the end of operation.
我认为,这种方法取决于初始请求和操作结束之间的时间差。
- For short-time operations ( < 10s ) I would just keep the request open and return response when operation finished;
- For long operations ( < 30m ) I would use servlet 3.0 or Comet model;
- For extremely long operations ( hours, days ) good enough way, as for me, is just client-based polling or Comet with big timeouts.
对于短时间操作(<10s),我只是保持请求打开并在操作完成时返回响应;
对于长时间操作(<30m),我会使用servlet 3.0或Comet模型;
对于极长的操作(小时,天),对我而言,只是基于客户端的轮询或具有大超时的Comet。
#3
0
I'm dealing now with the same situation and found the common approach of using Location
header response to give a resource that can be monitored to check status (by polling of course). That seems to be the best, but in my case, I'm not creating a resource so I don't have a location to check the status (my async process is just to build a cache page).
我正在处理相同的情况,并找到了使用Location头响应的常用方法,以提供可以监视的资源来检查状态(通过轮询当然)。这似乎是最好的,但在我的情况下,我不是创建资源,所以我没有位置来检查状态(我的异步过程只是建立一个缓存页面)。
You can always use your own headers to give an estimated time to complete the operation. Anyway I'm thinking of using Retry-After
header to give an estimated time. What do you guys think?
您始终可以使用自己的标头来估计完成操作的时间。无论如何,我正在考虑使用Retry-After标头来估计时间。你们有什么感想?
#4
0
I know this is old but I thought I'd chime in here to say that if what you want is something that can scale out in a stateless environment then you should go with your first option. You can perform the underlying operation anywhere and if you put the result in something like redis it will not matter to what web server the client makes subsequent polling requests. I'll usually put the polling interval in the response I sent to the client. When there a result is ready I will return the client a SEE OTHER that includes the id of the result in the URI.
我知道这已经老了,但我想我会在这里说,如果你想要的是可以在无状态环境中扩展的东西,那么你应该选择第一个选项。您可以在任何地方执行基础操作,如果您将结果放在像redis这样的内容中,那么客户端进行后续轮询请求的Web服务器也无关紧要。我通常会将轮询间隔放在我发送给客户端的响应中。当结果准备就绪时,我将向客户端返回一个SEE OTHER,其中包含URI中结果的id。