Java重试机制简单使用(基于guava-retrying实现)

一、简单介绍

  • Guava 是Java的工具集,提供了一些常用的便利的操作工具类,减少因为 空指针、异步操作等引起的问题BUG,提高开发效率。Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common annotations] 、字符串处理 [string processing] 、I/O 等等。
  • 在日常开发中,接口调用过程中出现异常是经常会遇到的,任何接口都会有不同概率的异常情况,对于可重入的接口,为了避免偶发性异常造成的服务不可用,重试机制就非常有必要了.guava-retrying 是一个非常灵活的重试组件,包含多种重试策略,扩展很方便。

二、相关依赖

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

三、演示demo

高阶的使用方式可以重点参考官方文档,基本的使用废话不多说,直接上代码:

package com.ideax.retry.guava;

import com.github.rholder.retry.*;
import com.google.common.base.Preconditions;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 基于Guava的重试机制
 *
 * @author zhangxs
 **/
public class GuavaRetryDemo {
    public static void retrySendMessage(String phone, String message) {
        // 定义重试规则(如果需要其他更详细的规则,建议看源码)
        Retryer<Boolean> retry = RetryerBuilder.<Boolean>newBuilder()
                .retryIfException()
                // 运行时异常时
                .retryIfRuntimeException()
                // call方法返回true时重试
                .retryIfResult(ab -> Objects.equals(ab, true))
                // 10秒后重试
                .withWaitStrategy(WaitStrategies.fixedWait(10, TimeUnit.SECONDS))
                // 重试n次,超过次数就...
                .withStopStrategy(StopStrategies.stopAfterAttempt(5))
                // 可以自定义监听器
                // .withRetryListener()
                .build();

        // 调用重试任务
        try {
            retry.call(() -> {
                try {
                    send(phone,message);
                    return false;
                } catch (Exception e) {
                    System.out.println("[" + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
                            .format(LocalDateTime.now()) + "]尝试重新发送:" + e.getMessage());
                    return true;
                }
            });
        } catch (ExecutionException | RetryException e) {
            e.printStackTrace();
        }
    }

    public static void send(String phone, String message) {
        // 参数校验
        Preconditions.checkNotNull(phone,"phone不能为空!");
        Preconditions.checkNotNull(message,"message不能为空!");

        // 您老的业务代码,千言万语都在这里了,比如通过第三方平台发送短信,随便随机抛个异常
        if (LocalDateTime.now().getSecond() % 3 == 0) {
            throw new RuntimeException("不好意思,短信平台已挂");
        }
        System.out.println("[" + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
                .format(LocalDateTime.now()) + "]短信发送成功:" + phone + "->" + message);
    }

    public static void main(String[] args) {
        retrySendMessage("18605998878","guava");
    }
}

四、参考

上一篇:socket__服务端于客户端


下一篇:Mysql日期时间