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

时间:2012-12-10 21:47:52

标签: java android httprequest

如果请求第一次失败,我希望为HttpClient实现HttpRequestRetryHandler

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

E(c) = 1/2(2 power (c) -1)

enter image description here

但是我现在很难在代码中实现它 使用HttpRequestRetryHandler。

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

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

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

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

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

我希望能有所帮助。