分享免费的编程资源和教程

网站首页 > 技术教程 正文

Spring异常重试框架Spring Retry spring异常处理机制

goqiw 2024-09-25 20:13:14 技术教程 49 ℃ 0 评论

Spring Retry支持集成到Spring或者Spring Boot项目中,而它支持AOP的切面注入写法,所以在引入时必须引入aspectjweaver.jar包。

快速集成的代码样例:

@Configuration
@EnableRetry
public class Application {
 @Bean
 public Service service() {
 return new Service();
 }
}
@Service
class Service {
 @Retryable(RemoteAccessException.class)
 public service() {
 // ... do something
 }
}

下面是基于Spring Boot项目的集成步骤:

POM:

 <!-- Spring Retry -->
 <dependency>
 <groupId>org.springframework.retry</groupId>
 <artifactId>spring-retry</artifactId>
 </dependency>
 <dependency>
 <groupId>org.aspectj</groupId>
 <artifactId>aspectjweaver</artifactId>
 </dependency>

Service:

package com.jsoft.springboottest.springboottest1;
import java.time.LocalTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 {
 
 private final static Logger logger = LoggerFactory.getLogger(RemoteService.class);
 
 @Retryable(value = { RemoteAccessException.class }, maxAttempts = 3, backoff = @Backoff(delay = 5000l, multiplier = 1))
 public void call() throws Exception {
 logger.info(LocalTime.now()+" do something...");
 throw new RemoteAccessException("RPC调用异常");
 }
 @Recover
 public void recover(RemoteAccessException e) {
 logger.info(e.getMessage());
 }
}

@Retryable注解

被注解的方法发生异常时会重试

  • value:指定发生的异常进行重试
  • include:和value一样,默认空,当exclude也为空时,所有异常都重试
  • exclude:指定异常不重试,默认空,当include也为空时,所有异常都重试
  • maxAttemps:重试次数,默认3
  • backoff:重试补偿机制,默认没有

@Backoff注解

  • delay:指定延迟后重试
  • multiplier:指定延迟的倍数,比如delay=5000l,multiplier=2时,第一次重试为5秒后,第二次为10秒,第三次为20秒

@Recover

当重试到达指定次数时,被注解的方法将被回调,可以在该方法中进行日志处理。需要注意的是发生的异常和入参类型一致时才会回调。

Controller:

package com.jsoft.springboottest.springboottest1.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.jsoft.springboottest.springboottest1.RemoteService;
@RestController
public class TestController {
 
 @Autowired
 private RemoteService remoteService;
 
 @RequestMapping("/show")
 public String show(){
 try {
 remoteService.call();
 } catch (Exception e) {
 // TODO Auto-generated catch block
 //e.printStackTrace();
 }
 return "Hello World"; 
 }
}

App:

package com.jsoft.springboottest.springboottest1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;
/**
 * Hello world!
 *
 */
@SpringBootApplication
@EnableRetry
public class App 
{
 public static void main( String[] args )
 {
 SpringApplication.run(App.class, args);
 }
}

效果:

说明:

1、使用了@Retryable的方法不能在本类被调用,不然重试机制不会生效。也就是要标记为@Service,然后在其它类使用@Autowired注入或者@Bean去实例才能生效。

2、要触发@Recover方法,那么在@Retryable方法上不能有返回值,只能是void才能生效。

3、使用了@Retryable的方法里面不能使用try...catch包裹,要在发放上抛出异常,不然不会触发。

4、在重试期间这个方法是同步的,如果使用类似Spring Cloud这种框架的熔断机制时,可以结合重试机制来重试后返回结果。

5、Spring Retry不只能注入方式去实现,还可以通过API的方式实现,类似熔断处理的机制就基于API方式实现会比较宽松。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表