天天看点

程序员不能不懂的Retry机制 Retry重试机制 Retry重试机制的使用

Retry重试机制

当我们调用一个接口时, 可能由于网络等原因造成第一次失败, 再去尝试就成功了, 这就是重试机制.

重试的解决方案有很多, 比如利用 try-catch-redo简单重试模式, 通过判断返回结果或监听异常来

判断是否重试, 具体可以看如下例子:

public void testRetry(){
        boolean result = false;
        try{
            result = load();
            if (!result){
                load(); //一次重试
            }
        }catch (Exception e){
            load(); //一次重试
        }
    }
           

但是这种策略有个问题就是: 正常逻辑和重试逻辑强耦合. 基于这个问题, 我们可以使用 Spring-Retry工具,

该工具把重试操作模板定制化, 可以设置重试策略和回退策略. 同时 重试执行实例保证线程安全.

Retry重试机制的使用

首先在pom.xml中引入所需的依赖:
<dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>
           
添加完依赖后, 需要在入口类Application中添加注解

@EnableRetry

开启retry重试:
@SpringBootApplication
@EnableRetry
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}
           
然后我们新建个接口RetryService:
/**
 * @Author wuwei
 * @Date 2019/12/8 8:22 下午
 */
public interface RetryService {
    AyMood findByIdRetry(String id);
}
           
接着创建实现类RetryServiceImpl:
/**
 * @Author wuwei
 * @Date 2019/12/8 8:22 下午
 */
@Service
public class RetryServiceImpl implements AyMoodService {
    
    @Override
    @Retryable(value = {BusinessException.class}, maxAttempts = 5,
    backoff = @Backoff(delay = 5000, multiplier = 2))
    public AyMood findByIdRetry(String id) {
        System.out.println("[findByIdRetry]方法重试失败了!!!");
        throw new BusinessException("retry");
    }

}

           
我们在方法中故意抛出

自定义异常BusinessException

,

关于自定义处理全局异常,请移步: https://blog.csdn.net/dummyo/article/details/103450968

@Retryable

:
  • value属性表示当出现哪些异常的时候触发重试
  • maxAttemps: 表示最大重试次数, 默认为3
  • delay表示重试的延迟时间
  • multiplier表示第n次重试是n-1次重试的多少倍.[例子中: 失败后第一次过5秒后重试, 第二次过10秒, 20秒]
我们写个测试方法来调用上述方法:
/**
 * @Author wuwei
 * @Date 2019/12/8 10:24 下午
 */
@RestController
@RequestMapping("/start")
public class TestController {
    
    @Autowired
    AyMoodService ayMoodService;
    
    @RequestMapping("/retry")
    public String findByIdRetry(){
        AyMood ayMood = ayMoodService.findByIdRetry("1");
        return "";
    }
}
           
然后在浏览器中请求这个接口, 会发现控制台一直在进行重试, 5次后就返回结果.
程序员不能不懂的Retry机制 Retry重试机制 Retry重试机制的使用

Over

如果觉得需要更多技术干货, 来我的CSDN 和 GitHub哦

CSDN: https://println.tk/

Github: https://github.com/uweii

继续阅读