REST与JAX-RS-处理长时间运行的操作
问题内容:
我有一个用JAX-
RS实现的REST服务。有些操作需要很长时间才能完成,可能需要15到30分钟。对于这些情况,我倾向于派遣一个后台线程来处理长时间运行的操作,然后立即以HTTP状态202
ACCEPTED进行响应。响应将包含一个带有URL的位置标头,客户端可使用该标头来轮询进度。
这种方法需要创建线程来处理长时间运行的操作,以便可以立即返回202 ACCEPTED。我也知道在Java EE容器中创建自己的线程通常是不好的做法!
我的问题如下:
- 人们是否同意这是正确的方法?
- 假设它是正确的,人们是否可以推荐一个“良好实践”解决方案,使我能够在后台调度长时间运行的操作并立即返回?
另外,为了避免管理自己的线程,我研究了JAX-RS异步服务器api。不幸的是,尽管这提高了服务器的吞吐量,但它不允许我立即以ACCEPTED响应。
泽西州规定:
Note that the use of server-side asynchronous processing model will not improve the
request processing time perceived by the client. It will however increase the
throughput of the server, by releasing the initial request processing thread back to
the I/O container while the request may still be waiting in a queue for processing or
the processing may still be running on another dedicated thread. The released I/O
container thread can be used to accept and process new incoming request connections.
任何帮助表示赞赏。谢谢!
问题答案:
我认为Jersey Async文档很好地解决了这个问题。这是一个简短的摘要:
@Path("/async/longRunning")
public class MyResource {
@GET
public void longRunningOp(@Suspended final AsyncResponse ar) {
executor.submit(
new Runnable() {
public void run() {
executeLongRunningOp();
ar.resume("Hello async world!");
} });
}
}
在文档中引用以下报价时:
请注意,使用服务器端异步处理模型不会缩短客户端感知的请求处理时间。(…)
我想你误会了一点。文档的作者试图在这里表达的是,异步处理不会仅仅靠自身来加快处理速度。但是可以使用以下示例立即返回响应:
return Response.status(Status.ACCEPTED).build();