From 7bad1ed0617794093c649771713c54a0bce05404 Mon Sep 17 00:00:00 2001 From: deepcloudlabs Date: Thu, 25 Jun 2020 01:17:34 +0300 Subject: [PATCH] implement retry template implement exponential backoff strategy --- .../lottery/config/RetryTemplateConfig.java | 29 +++++++++++++ ...tteryConsumerServiceWithRetryTemplate.java | 43 +++++++++++++++++++ .../lottery/service/SimpleDemoService.java | 12 ++++++ .../lottery/service/StudyRetryStrategy.java | 15 +++++-- 4 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 lottery-consumer-service/src/main/java/com/example/lottery/config/RetryTemplateConfig.java create mode 100644 lottery-consumer-service/src/main/java/com/example/lottery/service/LotteryConsumerServiceWithRetryTemplate.java diff --git a/lottery-consumer-service/src/main/java/com/example/lottery/config/RetryTemplateConfig.java b/lottery-consumer-service/src/main/java/com/example/lottery/config/RetryTemplateConfig.java new file mode 100644 index 0000000..fb5a1a9 --- /dev/null +++ b/lottery-consumer-service/src/main/java/com/example/lottery/config/RetryTemplateConfig.java @@ -0,0 +1,29 @@ +package com.example.lottery.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.retry.backoff.ExponentialBackOffPolicy; +import org.springframework.retry.policy.SimpleRetryPolicy; +import org.springframework.retry.support.RetryTemplate; + +/** + * + * @author Binnur Kurt + * + */ +@Configuration +public class RetryTemplateConfig { + @Bean + public RetryTemplate retryTemplate() { + RetryTemplate retryTemplate = new RetryTemplate(); + + ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy(); + exponentialBackOffPolicy.setInitialInterval(1000L); + retryTemplate.setBackOffPolicy(exponentialBackOffPolicy); + + SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(); + retryPolicy.setMaxAttempts(3); + retryTemplate.setRetryPolicy(retryPolicy); + return retryTemplate; + } +} diff --git a/lottery-consumer-service/src/main/java/com/example/lottery/service/LotteryConsumerServiceWithRetryTemplate.java b/lottery-consumer-service/src/main/java/com/example/lottery/service/LotteryConsumerServiceWithRetryTemplate.java new file mode 100644 index 0000000..0402431 --- /dev/null +++ b/lottery-consumer-service/src/main/java/com/example/lottery/service/LotteryConsumerServiceWithRetryTemplate.java @@ -0,0 +1,43 @@ +package com.example.lottery.service; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.retry.RecoveryCallback; +import org.springframework.retry.RetryCallback; +import org.springframework.retry.support.RetryTemplate; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import com.example.lottery.dto.LotteryResponse; + +@Service +public class LotteryConsumerServiceWithRetryTemplate { + @Autowired + private RetryTemplate retryTemplate; + + @Scheduled(fixedRate = 12_000) + public void doSomething() { + RetryCallback retryCallback = context -> { + System.err.println("Calling lottery service from LotteryConsumerServiceWithRetryTemplate..."); + var rt = new RestTemplate(); + var response = rt.getForObject("http://localhost:8001/lottery/api/v1/numbers?column=10", + LotteryResponse.class); + System.err.println(response); + return response; + }; + RecoveryCallback recoveryCallback = context -> { + System.err.println("Calling recoveryCallback from LotteryConsumerServiceWithRetryTemplate..."); + return new LotteryResponse(List.of(List.of(5, 10, 15, 20, 25, 30))); + }; + try { + var response = retryTemplate.execute(retryCallback, recoveryCallback); + System.out.println(response); + } catch (Exception e) { + System.err.println(e.getMessage()); + } + + } + +} diff --git a/lottery-consumer-service/src/main/java/com/example/lottery/service/SimpleDemoService.java b/lottery-consumer-service/src/main/java/com/example/lottery/service/SimpleDemoService.java index cbd990d..5aac1e0 100644 --- a/lottery-consumer-service/src/main/java/com/example/lottery/service/SimpleDemoService.java +++ b/lottery-consumer-service/src/main/java/com/example/lottery/service/SimpleDemoService.java @@ -13,6 +13,8 @@ public class SimpleDemoService { @Autowired private LotteryConsumerServiceWithCircuitBreaker srv; + @Autowired + private StudyRetryStrategy retryStrategy; @Scheduled(fixedRate = 2_000) public void doSomething() { @@ -23,4 +25,14 @@ public void doSomething() { String.format("Exception (%s) in doSomething(): %s", e.getClass().getName(), e.getMessage())); } } + + @Scheduled(fixedRate = 5_000) + public void doSomethingElse() { + try { + System.out.println(retryStrategy.getNumbers()); + } catch (Exception e) { + System.err.println( + String.format("Exception (%s) in doSomething(): %s", e.getClass().getName(), e.getMessage())); + } + } } diff --git a/lottery-consumer-service/src/main/java/com/example/lottery/service/StudyRetryStrategy.java b/lottery-consumer-service/src/main/java/com/example/lottery/service/StudyRetryStrategy.java index cd0ed50..46fd133 100644 --- a/lottery-consumer-service/src/main/java/com/example/lottery/service/StudyRetryStrategy.java +++ b/lottery-consumer-service/src/main/java/com/example/lottery/service/StudyRetryStrategy.java @@ -2,13 +2,16 @@ import java.net.SocketException; import java.net.SocketTimeoutException; +import java.util.List; import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Recover; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import com.example.lottery.dto.LotteryResponse; +import com.google.inject.Exposed; /** * @@ -17,12 +20,18 @@ */ @Service public class StudyRetryStrategy { - - @Retryable(value= {SocketTimeoutException.class, SocketException.class}, - maxAttempts = 3, backoff=@Backoff(delay = 3_000)) + + @Retryable(value = { SocketTimeoutException.class, // exponential backoff: 2^{n} * 3 seconds + SocketException.class }, maxAttempts = 3, backoff = @Backoff(multiplier = 2, delay = 3_000)) public LotteryResponse getNumbers() { System.err.println("Calling lottery service from StudyRetryStrategy..."); RestTemplate rt = new RestTemplate(); return rt.getForObject("http://localhost:8001/lottery/api/v1/numbers?column=10", LotteryResponse.class); } + + @Recover + public LotteryResponse getNumbersFallback(Exception e) { + return new LotteryResponse(List.of(List.of(1, 3, 5, 7, 9, 11), List.of(2, 4, 6, 8, 10, 12))); + } + }