gpt4 book ai didi

java - 设置 Rest 端点的超时

转载 作者:太空宇宙 更新时间:2023-11-04 11:56:54 27 4
gpt4 key购买 nike

我正在尝试对 http 端点施加时间限制。

在下面的例子中,我的目标是这个方法应该在5秒之前执行。如果花费更多时间,我想抛出异常并向客户端返回错误。

Spring : 4.1.7
Jersey 1.1.9

代码

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;


@Path("/pets")
@Component
public class PetsController {


@GET
@Produces({MediaTypeApi.JSON, MediaTypeApi.XML})
//Timeout of 5 secs
public List<Pet> getPets() {
//Return
}
}

考虑到线程的最佳利用,有什么更好的方法来处理这个问题。

最佳答案

编辑

在写这个答案时,我没有注意到 Jersey OP 正在使用的版本。 Jersey 2 中添加了异步 API,因此这个答案不是给定 OP 限制的答案。

编辑2

除了升级 Jersey 库之外,您还可以考虑将 api 迁移到 Spring MVC 并使用它们的异步 API(从 Spring 3.2 开始提供)。以 Spring 方式处理超时(使用 DeferredResult 对象):

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;

@RestController
@RequestMapping("/api")
public class AsyncController {

private static final TIMEOUT = 5000L;

private final AService aService;

@Inject
public AsyncController(final AService aService) {
this.aService = aService;
}

@RequestMapping(value = "/async-endpoint", method = RequestMethod.GET)
public DeferredResult<ResponseEntity<ADto>> asyncEndpoint() {

DeferredResult<ResponseEntity<ADto>> deferredResult = new DeferredResult<>(TIMEOUT);

CompletableFuture
.supplyAsync(() -> aService.aVeryExpensiveOperation())
.thenAccept(result -> {
deferredResult.setResult(new ResponseEntity<>(result, HttpStatus.OK));
})
.exceptionally(throwable -> {
deferredResult.setErrorResult(
throwable instanceof CompletionException ? throwable.getCause() : throwable);
return null;
});

return deferredResult;
}
}
<小时/>

原始答案:

an exampleJersey Asynchronous Server API Documentation做你想做的事:

import javax.ws.rs.container.Suspended;
import javax.ws.rs.container.TimeoutHandler;
import javax.ws.rs.core.Response;
import java.util.concurrent.TimeUnit;

@Path("/resource")
public class AsyncResource {

@GET
@Path("/timeoutAsync")
public void asyncGetWithTimeout(@Suspended final AsyncResponse asyncResponse) {
asyncResponse.setTimeoutHandler(new TimeoutHandler() {
@Override
public void handleTimeout(AsyncResponse asyncResponse) {
asyncResponse.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE).entity("Operation time out.").build());
}
});
asyncResponse.setTimeout(5, TimeUnit.SECONDS);

new Thread(new Runnable() {

@Override
public void run() {
String result = veryExpensiveOperation();
asyncResponse.resume(result);
}

private String veryExpensiveOperation() {
return "Very Expensive Operation with Timeout";
}
}).start();
}
}

请注意,在现实生活中,您可能会使用线程池线程,而不是像 this Jersey example 那样自己创建它。

关于java - 设置 Rest 端点的超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41296574/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com