When a third-party interface is invoked or MQ is used, network jitter or connection timeout occurs. Therefore, you need to try again. To make the processing more robust and less prone to failures, subsequent attempts sometimes help the failed operation to succeed. For example, a remote invocation of a Web service or RMI service due to a network failure or DeadLockLoserException in a database update might resolve itself after a short wait. To automate retries of these operations, Spring Batch has a RetryOperations policy. However, this Retry feature is separate from Spring Batch 2.2.0 and becomes the Spring Retry module.

Introduction of depend on

    <dependency>
        <groupId>org.springframework.retry</groupId>
        <artifactId>spring-retry</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
    </dependency>
Copy the code

Spring-retry and AspectJweaver dependencies need to be introduced.

Entrance class


@SpringBootApplication
@EnableRetry
public class SpringbootRetryApplication {

    public static void main(String[] args) { SpringApplication.run(SpringbootRetryApplication.class, args); }}Copy the code

EnableRetry interception on the entry class using the @enableretry annotation.

Service

@Service
public class PayService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private final int totalNum = 100000;

    @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5))
    public int minGoodsnum(int num) throws Exception {
        logger.info("Destocking begins." + LocalTime.now());
        try {
            int i = 1 / 0;
        } catch (Exception e) {
            logger.error("illegal");
        }
        if (num <= 0) {
            throw new IllegalArgumentException("Not the right amount");
        }
        logger.info("Inventory reduction execution completed" + LocalTime.now());
        returntotalNum - num; }}Copy the code

@retryable parameter descriptions:

  • Value: a retry will be performed only after the specified exception is thrown
  • Include: Like value, include is null by default. Exclude is also null by default
  • Exclude: Specifies the exception that is not to be processed
  • MaxAttempts: maximum number of retries. The default value is 3
  • Backoff: retry wait policy. This policy is used by default@Backoff.@BackoffThe default value is 1000L, we set it to 2000L; Multiplier defaults to 0, meaning that the retry is performed after a fixed pause of 1 second. If multiplier is set to 1.5, the first retry is 2 seconds, the second retry is 3 seconds, and the third retry is 4.5 seconds.

The test class

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRetryApplicationTests {
    @Autowired
    private PayService payService;

    @Test
    public void payTest(a) throws Exception {
        int store = payService.minGoodsnum(-1);
        System.out.println("Inventory is:"+ store); }}Copy the code

The console results are as follows:

As you can see, IllegalArgumentException is thrown three times later.

When the retries run out, RetryOperations can pass control to another callback, RecoveryCallback. Spring-retry also provides the @Recover annotation, which is used to resolve Retry failures by the @retryable method. Exceptions that are not invoked by the @Retryable method must be those that are not.

@Recover
public int recover(Exception e) {
    logger.warn("Inventory reduction failed!!" + LocalTime.now());
    return totalNum;
}
Copy the code

After adding the above methods in the Service, test.

As you can see, when the three retries are complete, the Recovery method is called and no exception is thrown again.

conclusion

This article focuses on spring-Retry simple applications in Spring Boot projects. It is easy to configure Retry policies based on annotations. The main scenario is when invoking third-party interfaces or using MQ. Network jitter or connection timeout may occur. In this case, you need to retry.

This article’s code: https://github.com/keets2012/Spring-Cloud_Samples/tree/master/springboot-retry

Subscribe to the latest articles, welcome to follow my official account

reference

  1. Springboot integration retry