Timeout Pattern — Resilient Microservice Design With Spring Boot

Need For Resiliency:

Why Timeout?:

  • Make the core services work always even when the dependent services are not available
  • We do not want to wait indefinitely
  • We do not want to block any threads
  • To handle network related issues and make the system remain functional using some cached responses.

Sample Application:

  • We have multiple microservices as shown above
  • Product service acts as product catalog and responsible for providing product information.
  • We have a separate service for product reviews and ratings
  • Whenever we look at the product details, product service sends the request to the rating service to get the reviews for the product.
  • We have other services like account-service, order-service and payment-service etc which is not relevant to this article discussion.
  • Product service is a core service without which the user can not place any order.
  • Product service depends on the rating service.

Common Util:

ReviewsDTO:

public class ReviewsDTO {

private String userFirstname;
private String userLastname;
private int rating;
private int productId;
private String comment;

// Getters & Setters

}

ProductRatingDTO:

public class ProductRatingDTO {

private double avgRating;
private List<ReviewsDTO> reviews;

// Getters & Setters

}

ProductDTO:

public class ProductDTO {

private int productId;
private String description;
private double price;
private ProductRatingDTO productRating;

//Getters & Setters

}

Rating MicroService:

RatingService:

RatingController:

@RestController
@RequestMapping("v1")
public class RatingController {

@Autowired
private RatingService ratingService;

@GetMapping("/ratings/{prodId}")
public ProductRatingDTO getRating(@PathVariable int prodId){
return this.ratingService.getRatingForProduct(prodId);
}

}

Product MicroService:

RestConfig:

@Configuration
public class RestConfig {

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

}

RatingService:

public interface RatingService {
ProductRatingDTO getRatings(int productId);
}

@Service
public class RatingServiceImpl implements RatingService {

@Value("${rating.service.url}")
private String ratingServiceUrl;

@Autowired
private RestTemplate restTemplate;

@Override
public ProductRatingDTO getRatings(int productId) {
String url = this.ratingServiceUrl + "/" + productId;
return this.restTemplate.getForObject(url, ProductRatingDTO.class);
}

}
rating:
service:
url: http://localhost:8081/v1/ratings

ProductService:

ProductController:

@RestController
@RequestMapping("v1")
public class ProductController {

@Autowired
private ProductService productService;

@GetMapping("/product/{id}")
public ProductDTO getProduct(@PathVariable int id){
return this.productService.getProduct(id);
}

}
//http://localhost:8080/v1/product/2
{
"productId":2,
"description":"Blood on the dance floor",
"price":12.45,
"productRating":{
"avgRating":4.5,
"reviews":[
{
"userFirstname":"slim",
"userLastname":"shady",
"rating":5,
"productId":2,
"comment":"best"
},
{
"userFirstname":"snoop",
"userLastname":"dogg",
"rating":4,
"productId":2,
"comment":"great"
}
]
}
}

Introducing Time Out:

@Configuration
public class RestConfig {

@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder){
return restTemplateBuilder
.setConnectTimeout(Duration.ofSeconds(3))
.setReadTimeout(Duration.ofSeconds(3))
.build();
}

}
//http://localhost:8080/v1/product/2
{
"productId":2,
"description":"Blood on the dance floor",
"price":12.45,
"productRating":{
"avgRating":0.0,
"reviews":[

]
}
}

Pros:

  • In this approach, we do not block any threads in the product service
  • Any unexpected events during network call will get timed out within 3 seconds.
  • Core services are not affected because of the poor performance of the dependent services.

Cons:

Source Code:

Summary:

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Vinoth Selvaraj

Vinoth Selvaraj

Principal Software Engineer — passionate about software architectural design, microservices.