千家信息网

Retry重试机制是什么意思

发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,这篇文章主要介绍"Retry重试机制是什么意思",在日常操作中,相信很多人在Retry重试机制是什么意思问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Retry重试机制
千家信息网最后更新 2025年12月03日Retry重试机制是什么意思

这篇文章主要介绍"Retry重试机制是什么意思",在日常操作中,相信很多人在Retry重试机制是什么意思问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Retry重试机制是什么意思"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1.前言

在项目开发中,有的时候,总是避免不了调用第三方服务接口,有的时候可能因为网络等情况的因素,我们需要重试几次才能调用成功,所以就需要一重试机制来保证接口的正常访问。

2.guava-retrying

这是谷歌guava提供的工具包,我们可以在项目中引入相应的包,很轻松实现重试访问。guava-retrying中大量运用的策略模式,可以自定义各种执行重试策略。下面是简单实用步骤。

①. pom引入
    com.google.guava    guava    19.0    com.github.rholder    guava-retrying    2.0.0
②. 基础业务代码

我这里实现一个对接口的简单访问,以此来模拟访问第三方接口。

@GetMapping("/retrytest")public Map retrytest(){    Map resultMap = Maps.newHashMap();    resultMap.put("id", 1001L);    resultMap.put("msg", "测试");    Map tokenMap = Maps.newHashMap();    tokenMap.put("token", UUID.randomUUID().toString());    resultMap.put("data", tokenMap);    return resultMap;}
③.Retryer Bean
  1. Retryer中定义重试的各种策略,在执行call方法的时候,会将这些重试策略一一使用。

  2. RetryListener是重试监听器,可以监听每次重试的过程。

  3. BlockStrategy是自定义阻塞策略。

@Beanpublic Retryer retry(){    RetryListener retryListener = new RetryListener() {        @Override        public  void onRetry(Attempt attempt) {            try {                if(attempt.hasException()){                    log.error("---"+ Arrays.toString(attempt.getExceptionCause().getStackTrace()));                }else {                    log.info("---"+ attempt.get().toString());                }            } catch (Exception e) {                e.printStackTrace();            }        }    };    BlockStrategy blockStrategy = new BlockStrategy() {        @Override        public void block(long sleepTime) throws InterruptedException {            LocalDateTime startTime = LocalDateTime.now();            long start = System.currentTimeMillis();            long end = start;            log.info("[SpinBlockStrategy]...begin wait.");            while (end - start <= sleepTime) {                end = System.currentTimeMillis();            }            //使用Java8新增的Duration计算时间间隔            Duration duration = Duration.between(startTime, LocalDateTime.now());            log.info("[SpinBlockStrategy]...end wait.duration={}", duration.toMillis());        }    };    Retryer retryer = RetryerBuilder.newBuilder()            //retryIf 重试条件            .retryIfException()            .retryIfRuntimeException()            .retryIfExceptionOfType(Exception.class)            .retryIfException(Predicates.equalTo(new Exception()))            //等待策略:每次请求间隔1s            //  .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS))            //停止策略 : 尝试请求3次            .withStopStrategy(StopStrategies.stopAfterAttempt(3))            //时间限制 : 某次请求不得超过2s , 类似: TimeLimiter timeLimiter = new SimpleTimeLimiter();            .withAttemptTimeLimiter(AttemptTimeLimiters.fixedTimeLimit(2, TimeUnit.SECONDS))            .withRetryListener(retryListener)            .withBlockStrategy(blockStrategy)            .build();    return retryer;}
④.Callable实现

编写retryer调用call方法的具体实现逻辑。

@Slf4jpublic class RetryCallable implements Callable {    private RestTemplate restTemplate;    public RetryCallable(RestTemplate restTemplate) {        this.restTemplate = restTemplate;    }    int times = 1;    @Override    public String call() {        log.info("call times={}", times++);        log.info("请求时间: {}", LocalDateTime.now());        //对远程地址的访问        return Objects.requireNonNull(                restTemplate.getForObject("http://localhost:8080/retrytest", Object.class)).toString();    }}
⑤. 重试器 call调用
@GetMapping("/hello")public Object hello(@RequestParam(required = false) String token){    log.info("hello "+ token);    Map result = null;    String msg = "";    try {        //定义请求实现 利用重试器调用请求        String callResult = retryer.call(new RetryCallable(restTemplate));        result = new Gson().fromJson(callResult, Map.class);    } catch (Exception e) {        e.printStackTrace();        msg = e.getMessage();        log.warn("请求失败:{}",e.getMessage());    }    HashMap resultData = Maps.newHashMap();    resultData.put("data",result);    resultData.put("token",token);    resultData.put("msg",msg);    return resultData;}

调用接口测试

2019-10-12 13:46:23.863  INFO 68012 --- [nio-8080-exec-1] com.wj.retry.controller.HelloController  : hello f5b78e95-87f7-435e-b9be-04bcb88ad0562019-10-12 13:46:23.865  INFO 68012 --- [pool-1-thread-1] com.wj.retry.controller.RetryCallable    : call times=12019-10-12 13:46:23.875  INFO 68012 --- [pool-1-thread-1] com.wj.retry.controller.RetryCallable    : 请求时间: 2019-10-12T13:46:23.8742019-10-12 13:46:24.068  INFO 68012 --- [nio-8080-exec-1] com.wj.retry.RetryApplication            : ---{msg=测试, data={token=eacb4a99-9ef9-4581-b8e5-28fdabac1c52}, id=1001}

若失败会调用多次(按照重试器中定义的策略)并,抛出异常

3.spring-retry

上面的实现会写相对较多的代码,若使用spring-retry则相对简单多了,可以基于注解实现

①. pom配置
    org.springframework.retry    spring-retry
②. 注解配置重试策略

@Retryable的参数说明:

  1. value:抛出指定异常才会重试

  2. include:和value一样,默认为空,当exclude也为空时,默认所以异常

  3. exclude:指定不处理的异常

  4. maxAttempts:最大重试次数,默认3次

  5. backoff:重试等待策略,默认使用@Backoff,@Backoff的value默认为1000L,我们设置为2000L;multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。

 @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5))public Object retry(@RequestParam(required = false) String token) {    String msg = "";    log.info("springretry");    log.info("请求时间: {}", LocalDateTime.now());    String resultStr = Objects.requireNonNull(            restTemplate.getForObject("http://localhost:8080/retrytest", Object.class)).toString();    Map result = new Gson().fromJson(resultStr, Map.class);    HashMap resultData = Maps.newHashMap();    resultData.put("data",result);    resultData.put("token",token);    resultData.put("msg",msg);    return resultData;}

最后在启动类上加上@EnableRetry注解开启重试机制。ok,就这样两个步骤就完成了

4.举例重试机制的运用

除了上面调用第三方服务接口可能会用到重试机制,在微服务项目中,服务之间的通信,重试机制可以说是随处可见。

在springcloud中Ribbon,feign,Hystrix等组件都可以自己配置重试机制,来达到提高能正常通信的成功率。

此外,在各种消息中间件中也都有重试机制的体现,例如kafka,消息发送失败可以重新发送,消息消费失败了,也可以配置重试机制,可以最大程度达到消息的不丢失。

5.目标服务要考虑的问题

可以考虑这么一个事情,若目标逻辑执行时间过长,超出了重试的等待时间,客户端就要发起重试,那么服务端就会出现重复调用执行的问题,所以,有重试机制就要考虑幂等性的问题。

到此,关于"Retry重试机制是什么意思"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

机制 策略 时间 服务 接口 意思 消息 问题 学习 配置 方法 时候 注解 第三方 项目 测试 实用 最大 成功 代码 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 服务器跑程序和本地跑程序 电脑网络服务器要多少钱一台 dell e7服务器 组织表达谱怎么分析数据库 lol游戏服务器黑屏 上海前端软件开发靠谱吗 计算机网络技术工作履历 代理服务器客户端 宝山区网络技术转让市价 软件技术里的软件开发与设计 广东专业软件开发需要多少钱 重庆初级软件开发.net 华为手机服务器系统密码 网络游戏软件开发合同 人大金仓数据库实例存储路径 互联网推广公司信任黔文科技 我的世界服务器登录 奉贤区上门软件开发咨询报价 网络安全事件演练流程 数据库oracle查询工具 浙江省网络安全知识挑战赛入口 做项目与服务器有关系吗 软件技术里的软件开发与设计 长沙智远软件开发有限公司 服务器的图片 网络安全工作由国家什么负责 浪潮服务器如何退出安全模式 广州思科系统中国网络技术 mysql数据库表在哪里 网络安全策略包括哪些
0