Spring Boot REST API - 请求超时?

问题描述 投票:17回答:6

我有一个Spring Boot REST服务,有时会将第三方服务作为请求的一部分。 我想在我的所有资源上设置一个超时(让我们说5秒),这样如果任何请求处理(整个链,从传入到响应)花费的时间超过5秒,我的控制器会响应HTTP 503而不是实际响应。 如果这只是一个Spring属性,例如设置,那将是非常棒的

spring.mvc.async.request-timeout=5000

但我没有运气。 我也尝试过扩展WebMvcConfigurationSupport并覆盖configureAsyncSupport:

@Override
public void configureAsyncSupport(final AsyncSupportConfigurer configurer) {
    configurer.setDefaultTimeout(5000);
    configurer.registerCallableInterceptors(timeoutInterceptor());
}

@Bean
public TimeoutCallableProcessingInterceptor timeoutInterceptor() {
    return new TimeoutCallableProcessingInterceptor();
}

没有运气。

我怀疑我必须手动计算所有第三方呼叫的时间,如果它们花费的时间太长,则抛出超时异常。 是对的吗? 或者是否有涵盖我所有请求端点的更简单,整体的解决方案?

java spring rest spring-boot timeout
6个回答
16
投票

如果希望spring.mvc.async.request-timeout=5000可以工作,则需要返回Callable<>

@RequestMapping(method = RequestMethod.GET)
public Callable<String> getFoobar() throws InterruptedException {
    return new Callable<String>() {
        @Override
        public String call() throws Exception {
            Thread.sleep(8000); //this will cause a timeout
            return "foobar";
        }
    };
}

9
投票

@Transactional注释采用超时参数,您可以在其中为@RestController中的特定方法指定超时(以秒为单位)

@RequestMapping(value = "/method",
    method = RequestMethod.POST,
    produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
@Transactional(timeout = 120)

3
投票

如果您使用的是RestTemplate,则应使用以下代码来实现超时

@Bean
public RestTemplate restTemplate() {
    return new RestTemplate(clientHttpRequestFactory());
}

private ClientHttpRequestFactory clientHttpRequestFactory() {
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
    factory.setReadTimeout(2000);
    factory.setConnectTimeout(2000);
    return factory;
}}

xml配置

<bean class="org.springframework.web.client.RestTemplate">
<constructor-arg>
    <bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory"
        p:readTimeout="2000"
        p:connectTimeout="2000" />
</constructor-arg>


3
投票

我建议您查看Spring Cloud Netflix Hystrix启动器来处理可能不可靠/慢速的远程调用。 它实现了断路器模式,适用于这种类型的东西。

有关更多信息,请参阅官方文档


3
投票

您可以在application.properties中尝试server.connection-timeout=5000 。 从官方文档

server.connection-timeout =#连接器在关闭连接之前等待另一个HTTP请求的时间(以毫秒为单位)。 未设置时,将使用连接器的特定于容器的默认值。 使用值-1表示没有(即无限)超时。

另一方面,您可能希望使用Circuit Breaker模式处理客户端的超时,正如我在此处的回答中所述: https//stackoverflow.com/a/44484579/2328781


-1
投票

在Spring属性文件中,您不能只为此属性指定一个数字。 您还需要指定一个单位。 所以你可以说spring.mvc.async.request-timeout=5000msspring.mvc.async.request-timeout=5s ,两者都会给你一个5秒的超时。

© www.soinside.com 2019 - 2024. All rights reserved.