我有一个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();
}
没有运气。
我怀疑我必须手动计算所有第三方呼叫的时间,如果它们花费的时间太长,则抛出超时异常。 是对的吗? 或者是否有涵盖我所有请求端点的更简单,整体的解决方案?
如果希望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";
}
};
}
@Transactional注释采用超时参数,您可以在其中为@RestController中的特定方法指定超时(以秒为单位)
@RequestMapping(value = "/method",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
@Transactional(timeout = 120)
如果您使用的是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>
您可以在application.properties中尝试server.connection-timeout=5000
。 从官方文档 :
server.connection-timeout =#连接器在关闭连接之前等待另一个HTTP请求的时间(以毫秒为单位)。 未设置时,将使用连接器的特定于容器的默认值。 使用值-1表示没有(即无限)超时。
另一方面,您可能希望使用Circuit Breaker模式处理客户端的超时,正如我在此处的回答中所述: https : //stackoverflow.com/a/44484579/2328781
在Spring属性文件中,您不能只为此属性指定一个数字。 您还需要指定一个单位。 所以你可以说spring.mvc.async.request-timeout=5000ms
或spring.mvc.async.request-timeout=5s
,两者都会给你一个5秒的超时。