15

I am using current Spring boot version (1.4.x) and wondering if it has any default timeout for api calls. I have tested it by putting breakpoints but it was keep waiting and didn't time-out. I was also trying to configure default timeout for all my spring-boot apps by using some annotation or yml settings.

I found couple of alternatives (one of them here) but using callable actually adding extra non-business logic code where setting something in xml bean is out of fashion in latest spring boot applications.

Gunjan Kumar
  • 667
  • 3
  • 8
  • 27

5 Answers5

19

You can try server.connection-timeout=5000 in your application.properties.From the official documentation:

server.connection-timeout= # Time in milliseconds that connectors will wait for another HTTP request before closing the connection. When not set, the connector's container-specific default will be used. Use a value of -1 to indicate no (i.e. infinite) timeout.

UPDATE: Just noticed that you use microservice architecture, so in case you need to handle timeouts when communicating between microservices, I would suggest handling it on the client side instead of the server side. If the microservice you are trying to call is overloaded and its performance degrades to the point where it drastically affects the user experience sometimes it's better to return some fallback data than just drop the request.

Imagine we have an e-commerce web-site that has microservice architecture and one of its microservices that gives recommendations to the user becomes extremely slow. In this case, the preferred solution would be to return some fallback data which could be top 10 popular products this month rather than showing 5xx error page to the customer. Moreover, in case subsequent requests fail with a timeout, we can make a decision to avoid sending requests to the 'recommendation-service' and return fallback data immediately. After some time we can try sending a request to the 'recommendation-service' again, and if it became healthy - just use it instead of the fallback data.

This is called Circuit Breaker pattern and there is already an implementation of it in a framework called Hystrix. Here is a nice article explaining it in depth: http://www.baeldung.com/spring-cloud-netflix-hystrix. Spring Cloud Feign + Spring Cloud Hystrix looks really nice especially taking into account that they work with Discovery services out-of-the-box (e.g. Spring Cloud Eureka).

Danylo Zatorsky
  • 5,856
  • 2
  • 25
  • 49
  • 19
    What is the default value of server.connection-timeout? – Shaohua Huang Jan 23 '19 at 02:20
  • What is "fallback data"? – deldev Mar 25 '19 at 02:20
  • 1
    For instance if you have an Amazon online store and you want to show recommendations for a user, but recommendation service is under a heavy load and responding very slowly. You can return fallback data immediately if such a scenario occurs. In this case, you can return top 100 the most popular items instead of waiting for recommendation serviceto respond. Circuit Breaker pattern is all about this idea. – Danylo Zatorsky Mar 25 '19 at 08:14
  • 1
    I think the answer is just wrong, `server.connection-timeout` is basically idle connection timeout. – geliba187 Oct 31 '19 at 01:52
  • server.connection-timeout does nothing. It isn't a request timeout. It is a timeout for idle connections. – BabyishTank Jul 26 '23 at 20:57
7

There are a couple of ways to do this:

1) Using ClientHttpRequestFactory with RestTemplate:

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

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

2) Second way is to use callable but I guess you have already explored that solution.

sebast26
  • 1,732
  • 1
  • 22
  • 38
tryingToLearn
  • 10,691
  • 12
  • 80
  • 114
7

I agree all above options and tried below option in my spring boot application. It works perfectly fine now. Below is the code sample as a bean. Now just need to @Autowire RestTemplate wherever(java class) I need it.

   @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        ((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setConnectTimeout(15000);
        ((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setReadTimeout(15000);

        return restTemplate;
    }
Gunjan Kumar
  • 667
  • 3
  • 8
  • 27
  • 3
    I think it's plagiarism. You copied my answer that was posted earlier and shared it as your own. :) It's alright, I won't report it but this is not encouraged. – tryingToLearn Sep 06 '22 at 12:15
1

The timeout can be set using the connectionTimeout property of Tomcat.

Please refer this answer how to set it for Tomcat.

Configuring maxKeepAliveRequests in Spring Boot embedded Tomcat

zeagord
  • 2,257
  • 3
  • 17
  • 24
0

You can create a configuration file using annotation @Configuration

For using RestTemplate:

` @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {

        return new RestTemplateBuilder()
                .setConnectTimeout(Duration.ofMillis(30000))
                .setReadTimeout(Duration.ofMillis(30000))
      

      .build();
}`

For WebClient Timeouts:

 @Bean
    public WebClient webClient() {
        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(
                        HttpClient.create().responseTimeout(Duration.ofMillis(30000))
                ))
                .build();
    }

After the configuration is done, in a controller or any other file where you want to use this RestTemplate or WebClient just autowire it like:

@Autowired
private RestTemplate restTemplate;

or

@Autowired
private WebClient webClient;
naib khan
  • 928
  • 9
  • 16