失败重试策略

来源:互联网 发布:org.apache.http post 编辑:程序博客网 时间:2024/06/06 20:24

简介

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

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;    }}

总结

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