Retry重试的封装及使用

177 阅读1分钟

1、代码

package com.wangzhan.controller;

public class RetryExecutorUtil {
    // 最大重试次数
    private int maxRetries;

    // 初始延迟(毫秒)
    private long delay;

    // 回退因子
    private int backoff;

    public RetryExecutorUtil() {
    }

    public RetryExecutorUtil(int maxRetries, long delay, int backoff) {
        this.maxRetries = maxRetries;
        this.delay = delay;
        this.backoff = backoff;
    }

    public Object execute(RetryCallback retryCallback) throws InterruptedException {
        Exception lastException = null;
        // 循环重试
        for (int i = 0; i < maxRetries; ++i) {
            try {
                // 执行方法
                return retryCallback.doInRetry();
            } catch (Exception e) {
                lastException = e;
                Thread.sleep(delay * ((long)Math.pow(backoff, i)));
            }
        }

        // 重试失败 向上抛出异常
        throw new RuntimeException("重试 " + maxRetries + " 次之后失败", lastException);
    }

    interface RetryCallback {
        Object doInRetry();
    }

    public static void main(String[] args) throws InterruptedException {
        // 创建具有特定参数(最大重试次数、初始延迟和回退因子)的 RetryExecutor 实例。
        RetryExecutorUtil retryExecutorUtil = new RetryExecutorUtil(3, 1000L, 2);

        Object data = null;
        try {
            data = retryExecutorUtil.execute(() -> {
                if (Math.random() > 0.99) {
                    System.out.println("数据获取成功!!!");
                    return "data";
                } else {
                    System.out.println("获取数据失败, 重试中...");
                    throw new RuntimeException("获取数据失败");
                }
            });
        } catch (RuntimeException e) {
            // 捕获异常的数据,存入数据库,后期使用定时任务再次进行重试
            System.out.println("捕获异常的数据。。。。。。。。");
            //throw new RuntimeException(e);
            e.printStackTrace();
            return;
        }

    }
}

2、执行结果

image.png