preface
Some scenarios require us to retry some tasks under abnormal conditions. For example, when calling a remote RPC service, the first call may fail due to network jitter. We can restore normal after several attempts. Spring retry is a spring based retry framework provided by spring, which is very easy to use.
Official website address: GitHub - spring-projects/spring-retry
instructions
1. Introducing maven dependency
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>1.1.2.RELEASE</version> </dependency>
2. Add @ Retryable and @ Recover annotations
package hello; import org.springframework.remoting.RemoteAccessException; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Recover; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; @Service public class RemoteService { @Retryable(value= {RemoteAccessException.class},maxAttempts = 3,backoff = @Backoff(delay = 5000l,multiplier = 1)) public void call() throws Exception { System.out.println("do something..."); throw new RemoteAccessException("RPC Call exception"); } @Recover public void recover(RemoteAccessException e) { System.out.println(e.getMessage()); } }
@Retryable annotation
When an exception occurs in the annotated method, it will be retried
value: specify the exception to retry
include: like value, it is empty by default. When exclude is also empty, all exceptions will be retried
exclude: Specifies that the exception will not be retried. It is empty by default. When include is also empty, all exceptions will be retried
Maxattempts: number of retries. The default is 3
backoff: retry compensation mechanism, not available by default
@Backoff annotation
Delay: retry after specifying a delay
Multiplier: Specifies the multiple of the delay. For example, when delay = 5000L and multiplier = 2, the first retry is 5 seconds, the second is 10 seconds, and the third is 20 seconds
@Recover
When the retry reaches the specified number of times, the annotated method will be called back, and log processing can be carried out in this method. It should be noted that the callback will only occur when the exception is consistent with the input parameter type@ Recover requires that the return value of the annotated method must be consistent with the return value of the annotated method of @ Retryable, otherwise the @ recover annotated method will not be called.
3. Start container and test in SpringBoot mode
Add @ EnableRetry annotation to enable retry function.
package hello; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.retry.annotation.EnableRetry; @SpringBootApplication @EnableRetry public class Application { public static void main(String[] args) throws Exception { ApplicationContext annotationContext = new AnnotationConfigApplicationContext("hello"); RemoteService remoteService = annotationContext.getBean("remoteService", RemoteService.class); remoteService.call(); } }
Operation results:
16:50:51.012 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry: count=0
do something...
16:50:51.025 [main] DEBUG org.springframework.retry.backoff.ExponentialBackOffPolicy - Sleeping for 5000
16:50:56.026 [main] DEBUG org.springframework.retry.support.RetryTemplate - Checking for rethrow: count=1
16:50:56.026 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry: count=1
do something...
16:50:56.026 [main] DEBUG org.springframework.retry.backoff.ExponentialBackOffPolicy - Sleeping for 5000
16:51:01.026 [main] DEBUG org.springframework.retry.support.RetryTemplate - Checking for rethrow: count=2
16:51:01.027 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry: count=2
do something...
16:51:01.027 [main] DEBUG org.springframework.retry.support.RetryTemplate - Checking for rethrow: count=3
16:51:01.027 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry failed last attempt: count=3
RPC call exception
Note: for non idempotent requests (such as new and update operations), do not use retry, which will have a great impact on data consistency.
Recommended reading:
- Official project page
https://github.com/spring-projects/spring-retry - spring-retry
http://www.itclj.com/blog/59940a4081c06e672f942ae1 - Spring Retry
https://www.cnblogs.com/jtlgb/p/6813164.html - Spring retry and detailed explanation
https://yq.aliyun.com/articles/92899 - Spring retry (1. Concept and basic usage) - brief book