如何使用指数退避实现HttpRequestRetryHandler?

我希望在第一次请求失败的情况下为HttpClient实现HttpRequestRetryHandler 。

我还希望为后续重试实施指数退避 。 在数学上它可以实现为

E(c)= 1/2(2次幂(c)-1)

在此处输入图像描述

但是我现在很难在HttpRequestHtryHandler的代码中实现它。

HttpRequestRetryHandler不允许你那个级别的控制; 如果你想做一些非常具体的事情,我建议你实现类似Handler的东西,你可以用延迟执行Runnables,例如Handler.postDelayed()根据你的公式增加延迟。

Handler mHandler = new Handler(); int mDelay = INITIAL_DELAY; // try request mHandler.postDelayed(mDelay, new Runnable() { public void run() { // try your request here; if it fails, then repost: if (failed) { mDelay *= 2; // or as per your formula mHandler.postDelayed(mDelay, this); } else { // success! } } }); 

这是一个带退避算法的好框架 – https://github.com/rholder/guava-retrying

我使用guava-retrying来重试任意函数调用的策略。

我将它与我编写的库Guavaberry集成,其中包含几个等待策略,可以轻松构建一个固定的指数退避,并结合随机间隔(又称抖动): ExponentialJitterWaitStrategy

例如,建立一个上限为15秒的指数退避,并且在可调用时的抖动为50%:

 Retryer retryer = RetryerBuilder.newBuilder() .retryIfResult(Predicates.isNull()) .withWaitStrategy(WaitStrategies.exponentialJitterWait(Duration.ofSeconds(15), 0.5D)) .build(); retryer.call(callable); 

该库经过充分测试和记录,可以通过Maven Central轻松集成。

我希望这可以有所帮助。