• 失败重试策略与思考


    简介

    自己封装的失败重试策略,比较适合访问网络或者蓝牙通信的时候任务失败重试,当失败次数达到预定的次数之后,就会提示本次任务失败。
    以下是代码的结构:
    《失败重试策略》

    RetryPolicyI是失败重试接口;
    AbstractRetryPolicy继承了接口,并实现了任务执行重试的逻辑;
    FixedRetryPlicy固定时间的重试;
    LinearRetryPlicy线性增加时间的重试;
    RandomRetryPolicy随机时间的重试;

    重试接口和抽象类

    RetryPolicyI

    public interface RetryPolicyI {
        void tryCall(Callable<Void> callable,Class<? extends Throwable> exception) throws Exception; }

    AbstractRetryPolicy

    当请求失败,如果请求次数小于最多尝试的次数,则先等待一段时间再继续执行;如果已经超过了最多尝试次数,则直接抛出异常,执行失败。

    public abstract class AbstractRetryPolicy implements RetryPolicyI {
    
        private String tag = "AbstractRetryPolicy";
    
        private int maxAttempts;//最多尝试次数
    
        public AbstractRetryPolicy(int maxAttempts) {
            this.maxAttempts = maxAttempts;
        }
    
        @Override
        public void tryCall(Callable<Void> callable, Condition condition, Class<? extends Throwable> exception) throws Exception {
            int attempts = 0;
            while (attempts <= maxAttempts) {
    
                try {
                    LogUtil.getInstance().ilog(tag,"第"+attempts+"次call");
                    callable.call();
                    break;
                } catch (Exception e) {
                    LogUtil.getInstance().elog(tag,"retry请求出现异常"+e);
                    attempts++;
                    if ((exception != null) && (exception.isAssignableFrom(e.getClass()))
                            && !(attempts >= maxAttempts)) {
                        Thread.sleep(getDelay(attempts));
                        LogUtil.getInstance().ilog(tag,"retry异常,重新请求");
                    } else {
                        LogUtil.getInstance().elog(tag,"请求失败,抛出异常 "+e);
                        throw e;
                    }
                }
            }
        }
    
        protected abstract long getDelay(int attempts);
    }

    具体重试实现

    等待固定时间重试

    根据传入的initialDelay参数来确定等待时间。

    public class FixedRetryPolicy extends AbstractRetryPolicy{
    
        private long initialDelay;
    
        public FixedRetryPolicy(int maxAttempts,long initialDelay) {
            super(maxAttempts);
            this.initialDelay = initialDelay;
        }
    
        @Override
        protected long getDelay(int attempts) {
            return initialDelay;
        }
    }

    等待时间线性增加

    等待的时间为:固定等待时间*尝试次数,尝试越多次,等待时间越久。

    public class LinearRetryPolicy extends AbstractRetryPolicy {
        private long initialDelay;
    
        public LinearRetryPolicy(long initialDelay, int maxAttempts) {
            super(maxAttempts);
            this.initialDelay = initialDelay;
        }
    
        @Override
        protected long getDelay(int attempts) {
            return attempts * initialDelay;
        }
    }

    随机等待时间

    每次等待时间是最长等待时间和最短等待时间中间的一个值。

    public class RandomRetryPolicy extends AbstractRetryPolicy{
    
        private long min;
        private long max;
    
        public RandomRetryPolicy(int maxAttempts,long min,long max){
            super(maxAttempts);
            this.min = min;
            this.max = max;
        }
    
        @Override
        protected long getDelay(int attempts) {
            long delay = (long)(Math.random()*(max - min)) + min;
            return delay;
        }
    }

    总结

    非常简单又好用的一个失败重试策略框架,还可以在此基础上增加超时的功能,当任务执行超过预定的时间之后,可以抛出异常,表示本次任务执行失败,继续下一个任务的执行。

  • 相关阅读:
    拉格朗日乘数法
    线性判别分析(Linear Discriminant Analysis)
    有监督学习 和 无监督学习
    Jenkins入门知识
    vs技巧总结
    jenkins 神奇变量
    ubuntu12.04 折腾流水
    ubuntu 12.04 右上角的网络连接图标突然消失不见
    ubuntu 12.04 上网体验
    JIRA 初体验
  • 原文地址:https://www.cnblogs.com/thinkingthigh/p/13578112.html
Copyright © 2020-2023  润新知