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.