Configure and Implement timeout for Spring Boot REST service
This post will discuss how to configure and implement a timeout for a Spring Boot REST service.
A Spring Boot REST service timeout is a situation where a request to a Spring Boot REST API takes longer than a specified time limit and fails to return a response. This can happen due to various reasons, such as network latency, slow external services, heavy load, or inefficient code. A timeout can affect the user experience and the reliability of the service, so it is important to handle it properly and gracefully.
There are several ways to configure and implement a timeout for a Spring Boot REST service, depending on the level and scope of the timeout. Some of the possible methods are:
1. Using application.properties
A simple and global way to set a timeout for all asynchronous requests handled by the Spring MVC framework is using the spring.mvc.async.request-timeout property in application.properties file. This property specifies the time, in milliseconds, that the server will wait for the async request to be completed before sending a 503 Service Unavailable error. For example, setting spring.mvc.async.request-timeout=5000 will cause any request that takes longer than 5 seconds to return a 503 error code. However, this method only works for requests that return a Callable<?> or a DeferredResult<?> as the response type, which are used to support asynchronous processing in Spring MVC.
Alternatively, we can use the server.connection-timeout property in application.properties file to set a global timeout for all incoming requests handled by the embedded server (Tomcat by default) used by Spring Boot. The property value is in milliseconds and can be specified in the application.properties file or as an environment variable. For example, setting server.connection-timeout=5000 will cause any request that takes longer than 5 seconds to return a 504 Gateway Timeout error. However, this method only works for requests that are slow to send their data to the server, not for requests that are slow to receive data from the server.
2. Using RestTemplate Class
Finally, we can use the Spring’s RestTemplate class to make HTTP requests to external services and configure its timeout properties. We can use the setConnectTimeout() and setReadTimeout() methods of the SimpleClientHttpRequestFactory class to set the connection and read timeouts, in milliseconds, respectively. For example, we can create a bean of RestTemplate with custom timeouts as follows:
|
1 2 3 4 5 6 7 |
@Bean public RestTemplate restTemplate() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(3000); // 3 seconds factory.setReadTimeout(5000); // 5 seconds return new RestTemplate(factory); } |
Now, we can use this bean to make HTTP requests with timeouts.
3. Using @Transactional Annotation
We can use the @Transactional annotation on our service methods that interact with the database queries and specify a timeout value. This value indicates the time, in seconds, that the transaction manager will wait for the transaction to be completed before rolling it back. The annotation can be applied at the class level or the method level, and it supports transaction management and rollback in case of a timeout.
For example, setting @Transactional(timeout = 5) will cause any database query or call that takes longer than 5 seconds to throw an exception and roll back the transaction. However, this method works only for requests that involve database operations with Spring-managed transactions.
4. Using WebClient Class
This is a way to set a timeout for external HTTP calls that are part of a request. The class is part of the Spring WebFlux module and provides a reactive and non-blocking way to perform HTTP requests. The class has various methods to configure the timeout for each request, such as connectTimeout(), responseTimeout(), or exchange() with a TimeoutException.
For example, setting .connectTimeout(Duration.ofSeconds(5)) will cause any HTTP connection that takes longer than 5 seconds to throw an exception. However, this method only works for requests that involve external HTTP calls with Spring WebFlux.
5. Using Resilience4j Library
We can use the Resilience4j library, which provides various features for fault tolerance and resilience, such as circuit breakers, bulkheads, rate limiters, and time limiters. A time limiter allows us to set a timeout for a method invocation and handle the result or the exception accordingly. For example, we can use the @TimeLimiter annotation on our service methods and specify a name value that refers to a time limiter configuration. For example, @TimeLimiter(name = "myService") will apply the time limiter configuration named "myService" to the method.
That’s all about configuring and implementing a timeout for a Spring Boot REST service.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)