Example of spring boot using spring retry mechanism

Time:2020-11-24

When we call the interface, it may fail due to network reasons. If we try again, we will succeed. This is the retrial mechanism. Be careful to use retrying when it is not idempotent.

Tips: idempotent

The definition of idempotency in http / 1.1 is that one or more requests for a resource should have the same result for the resource itself (except for network timeout and other issues). In other words, the impact of any multiple execution on the resource itself is the same as that of one execution.

Spring retry is used for annotation

(1) Maven dependence

<! -- retry mechanism -- >
<dependency>
  <groupId>org.springframework.retry</groupId>
  <artifactId>spring-retry</artifactId>
  <version>1.2.4.RELEASE</version>
</dependency>

<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.4</version>
</dependency>

(2) Add annotation @ enableretry to configuration class


@EnableRetry
@Configuration
public class RetryConfiguration {

}

(3) Service method writing

@Retryable note:

Value: throw the specified exception before retrying

Include: same as value, it is empty by default. When exclude is also empty, all exceptions will occur by default

Exclude: Specifies the exception that is not handled

Maxattempts: maximum number of retries, 3 times by default

Backoff: retrying and waiting policy, @ backoff is used by default, and the value of @ backoff is 1000L by default; multiplier (specify the delay multiple)

@Recover note:

When the number of retries reaches a specified number of times, the annotated method will be called back

The type of exception occurred needs to be consistent with the parameter of the @ recover annotation

@Methods annotated with retryable cannot have return values, otherwise @ recover annotated methods are invalid

@Service
public class RetryService {

 private Logger logger = LoggerFactory.getLogger(RetryService.class);

 @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 2))
 public void devide(double a, double b){
   logger.info ("start division operation");
   if (b == 0) {
     throw new RuntimeException();
   }
   logger.info("{} / {} = {}", a, b, a / b);
 }

 @Recover
 public void recover() {
   logger.error ("dividend cannot be 0");
 }

}

(4) Testing

@RunWith(SpringRunner.class)
@SpringBootTest
public class BootdemoApplicationTests {

  @Autowired
  private RetryService retryService;

  private Logger logger = LoggerFactory.getLogger(BootdemoApplication.class);

  @Test
  public void retryTest() {
    //int count = retryService.retry(-1);
    retryService.retry(-1);
    // logger.info ("inventory is: + count)";
  }
}

matters needing attention

@Retryable cannot be used in this class, otherwise it will not take effect. If execute is called directly, the retry mechanism will not take effect. If you call devide, the retry will take effect.

public void execute(double a, double b) throws DevideException {
    devide(a, b);
  }

  @Retryable(value = DevideException.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 2))
  public void devide(double a, double b) throws DevideException {
    logger.info ("start division operation");
    if (b == 0) {
      Throw new devideexception ("dividend cannot be 0");
    }
    logger.info("{} / {} = {}", a, b, a / b);
  }

Using @ retryable cannot use try catch to catch exceptions is simple

The above is the whole content of this article, I hope to help you in your study, and I hope you can support developeppaer more.