guava的重试机制guava-retrying使用

1,添加maven依赖

<dependency>
      <groupId>com.github.rholder</groupId>
      <artifactId>guava-retrying</artifactId>
      <version>2.0.0</version>
    </dependency>

2,定义重试机制

Retryer<CMSResultDTO> smsRetryer = RetryerBuilder.<CMSResultDTO>newBuilder()
.retryIfResult(cmsResultDTO->cmsResultDTO.getCode() != SM_SUCCESS_CODE)  // 短信返回的码不是200要重试
.retryIfResult(Predicates.<CMSResultDTO>isNull())            // 返回的数据是null要重试
.retryIfExceptionOfType(Exception.class)                    // 返回的异常错误类
.withStopStrategy(StopStrategies.stopAfterAttempt(ATTEMPT_NUM))
.withWaitStrategy(WaitStrategies.fixedWait(SLEEP_TIME, TimeUnit.SECONDS))    // 隔1秒重试
.withRetryListener(new SMRetryListener<>())
.build();

3,定义要重试的任务

 Callable<CMSResultDTO> task = ()->{
            log.info("sm input param:type=>{}, interCode=>{}, mobile=>{}, pair=>{}",
                    type, interCode, mobile, pair);
            CMSResultDTO cmsResultDTO = cmsService.sendMessage(type, interCode, mobile, pair);
            log.info("sm return data:{}", JSON.toJSONString(cmsResultDTO));
            return cmsResultDTO;
        };

4,重试机制重试任务

CMSResultDTO cmsResultDTO = null;
        try {
            cmsResultDTO = smsRetryer.call(task);
        } catch (ExecutionException e) {
            log.error("SM ExecutionException", e);
        } catch (RetryException e) {
            log.error("SM RetryException", e);
        }
        return cmsResultDTO;

以下是一个关于重试发短信的完整例子

/**
     * 重试机制 发送短信接口支持国际码
     * @param type 模版号
     * @param interCode 国际码
     * @param mobile 手机号码
     * @param pair 参数对
     * @return 消息发送结果,包括发送状态和消息标识
     */
    public CMSResultDTO retrySendMessage(Integer type, String interCode, String mobile, Map<String, String> pair) throws CMSQueueException, CMSSendException {
        Preconditions.checkNotNull(type, "type不能为null");
        Preconditions.checkNotNull(interCode, "interCode不能为null");
        Preconditions.checkNotNull(mobile, "mobile不能为null");
        Preconditions.checkNotNull(pair, "pair不能为null");

        Callable<CMSResultDTO> task = ()->{
            log.info("sm input param:type=>{}, interCode=>{}, mobile=>{}, pair=>{}",
                    type, interCode, mobile, pair);
             //调用第三方发短信接口,得到返回值,第一时间记录到log中
            CMSResultDTO cmsResultDTO = cmsService.sendMessage(type, interCode, mobile, pair);
            log.info("sm return data:{}", JSON.toJSONString(cmsResultDTO));
            return cmsResultDTO;
        };
        //定义重试的机制原理
        Retryer<CMSResultDTO> smsRetryer = RetryerBuilder.<CMSResultDTO>newBuilder()
                .retryIfResult(cmsResultDTO->cmsResultDTO.getCode() != SM_SUCCESS_CODE)  // 短信返回的码不是200要重试
                .retryIfResult(Predicates.<CMSResultDTO>isNull())            // 返回的数据是null要重试
                .retryIfExceptionOfType(Exception.class)                    // 返回的异常错误类
                .withStopStrategy(StopStrategies.stopAfterAttempt(ATTEMPT_NUM))
                .withWaitStrategy(WaitStrategies.fixedWait(SLEEP_TIME, TimeUnit.SECONDS))    // 隔1秒重试
                //监听器
                .withRetryListener(new SMRetryListener<>())
                .build();

        CMSResultDTO cmsResultDTO = null;
        try {
        //执行任务的重试,得到返回结果
            cmsResultDTO = smsRetryer.call(task);
        } catch (ExecutionException e) {
            log.error("SM ExecutionException", e);
        } catch (RetryException e) {
            log.error("SM RetryException", e);
        }
        return cmsResultDTO;
    }

    //自定义的监听器
    /**
     * 重试监听器
     * @param <CMSResultDTO>
     */
    private class SMRetryListener<CMSResultDTO> implements RetryListener {

        @Override
        public <CMSResultDTO> void onRetry(Attempt<CMSResultDTO> attempt) {
            log.info("[retry]time=" + attempt.getAttemptNumber());
            if (attempt.hasException()) {
                log.error("retry exception", attempt.getExceptionCause());
            }
            if (attempt.hasResult()) {
                if (attempt.getResult() == null) {
                    log.info("retry return data is null");
                } else {
                    log.info("retry return data is:{}", JSON.toJSONString(attempt.getResult()));
                }
            }
        }

    }

  

原文地址:https://www.cnblogs.com/webwangbao/p/9229001.html

时间: 2024-11-05 13:26:15

guava的重试机制guava-retrying使用的相关文章

使用Guava retryer优雅的实现接口重试机制

转载自: 使用Guava retrying优雅的实现接口重调机制 Guava retrying:基于 guava 的重试组件 实际项目中,为了考虑网络抖动,加锁并发冲突等场景,我们经常需要对异常操作进行重试.优雅的重试 其实就是将业务处理逻辑和重试逻辑分离. 下面是原文地址: API 接口调用异常和网络异常在我们日常开发中经常会遇到,这种情况下我们需要先重试几次才能将其标识为错误并在确认错误之后发送异常提醒. Guava retrying 可以灵活的实现这一功能.Guava retrying在支

Volley超时重试机制详解

Volley超时重试机制 基础用法 Volley为开发者提供了可配置的超时重试机制,我们在使用时只需要为我们的Request设置自定义的RetryPolicy即可. 参考设置代码如下: int DEFAULT_TIMEOUT_MS = 10000; int DEFAULT_MAX_RETRIES = 3; StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<S

Rocket重试机制,消息模式,刷盘方式

一.Consumer 批量消费(推模式) 可以通过 consumer.setConsumeMessageBatchMaxSize(10);//每次拉取10条 这里需要分为2种情况 Consumer端先启动 Consumer端后启动.   正常情况下:应该是Consumer需要先启动 注意:如果broker采用推模式的话,consumer先启动,会一条一条消息的消费,consumer后启动会才用批量消费 Consumer端先启动 1.Consumer.java package quickstart

Guava学习笔记:guava中的Preconditions使用

Guava学习笔记:guava中的Preconditions使用 转载:http://outofmemory.cn/java/guava/base/Preconditions google guava的base包中提供的Preconditions类用来方便的做参数的校验,他主要提供如下方法: checkArgument 接受一个boolean类型的参数和一个可选的errorMsg参数,这个方法用来判断参数是否符合某种条件,符合什么条件google guava不关心,在不符合条件时会抛出Illeg

Guava学习笔记:guava中对字符串的操作

Guava学习笔记:guava中对字符串的操作 转载:http://outofmemory.cn/java/guava/base/Strings 在google guava中为字符串操作提供了很大的便利,有老牌的判断字符串是否为空字符串或者为null,用指定字符填充字符串,以及拆分合并字符串,字符串匹配的判断等等. 下面我们逐一了解这些操作: 1. 使用com.google.common.base.Strings类的isNullOrEmpty(input)方法判断字符串是否为空        

Guava学习笔记:guava的不可变集合

Guava学习笔记:guava的不可变集合 不可变集合的意义 不可变对象有很多优点,包括: 当对象被不可信的库调用时,不可变形式是安全的: 不可变对象被多个线程调用时,不存在竞态条件问题 不可变集合不需要考虑变化,因此可以节省时间和空间.所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节): 不可变对象因为有固定不变,可以作为常量来安全使用. 创建对象的不可变拷贝是一项很好的防御性编程技巧.Guava为所有JDK标准集合类型和Guava新集合类型都提供了简单易用的不可变版本. 

Guava学习笔记:guava Throwables帮你处理异常,抛出异常

Guava学习笔记:guava Throwables帮你处理异常,抛出异常 guava类库中的Throwables提供了一些异常处理的静态方法,这些方法的从功能上分为两类,一类是帮你抛出异常,另外一类是帮你处理异常. 也许你会想:为什么要帮我们处理异常呢?我们自己不会抛出异常吗? 假定下面的方法是我们要调用的方法.     public void doSomething() throws Throwable {         //ignore method body     }     pub

jedis超时重试机制注意事项

最近使用redis集群进行incr操作,总是发现计数不准确,后来经过检查发现redis在执行incr超时会执行重试机制,造成计数不准确,测试代码: /** * incrf: * 将 key 中储存的数字值增一. 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作. 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误. 本操作的值限制在 64 位(bit)有符号数字表示之内. 这是一个针对字符串的操作,因为 Redis 没有专用的整数类型,

为你的代码加上一层重试机制

为代码加上重试机制 1.前言:对于经常跟网络编程打交道的你来说,并不是你的每次Request,Server都会给你想要的Response.重试机制虽然并不能解决这种情况,但是却可以大大减少这种情况的发生. 2.介绍下重试机制类:RetryUtil.cs 使用了委托,代码很短,也不难理解. 1 public class RetryUtil 2 { 3 public delegate void NoArgumentHandler(); 4 /// <summary> 5 /// retry mec