web-dev-qa-db-ja.com

Spring RestTemplate:指数バックオフ再試行ポリシー

GCMについて読んでいます: https://developers.google.com/cloud-messaging/server

要件の1つは、サーバーが次のことができる必要があることです。

  • リクエストを処理し、指数バックオフを使用して再送信します。

SpringBootからのバックエンドにSpringRestTemplateを使用しています。ドキュメントに再試行ポリシーを設定するために使用できる方法がないようです: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/ web/client/RestTemplate.html

また、グーグルで検索したところ、RetryTemplateが見つかりましたが、これはSpring Batchの一部であり、RestTemplateを拡張していないため、Rest操作ではなく、大量のトランザクションの処理などのSpringBatch操作に使用されることになっています。 : http://docs.spring.io/spring-batch/2.1.x/apidocs/org/springframework/batch/retry/support/RetryTemplate.html

Spring RestTemplateで指数バックオフを使用する方法はありますか?

11
Simon

良い一日!

カスタム Sleeper クラスを実装することで、望ましい動作を実現できると思います。

次に、次のように、このスリーパーを BackOffPolicy に設定する必要があります。

public class RetryTest {

  public static final Logger LOG = LoggerFactory.getLogger(RetryTemplate.class);

  @org.junit.Test
  public void testRT() {
    RetryTemplate retryTemplate = new RetryTemplate();
    final SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
    retryPolicy.setMaxAttempts(5);
    retryTemplate.setRetryPolicy(retryPolicy);

    Sleeper sleeper = new Sleeper() {
      private long timeToSleep = 0;
      @Override
      public void sleep(long timeout) throws InterruptedException {
        if (timeToSleep ==0) {
          timeToSleep = timeout;
        } else {
          timeToSleep = (long) (timeToSleep * Math.E);
        }
        LOG.warn("sleeping for: {}", timeToSleep);
        Thread.sleep(timeToSleep);
      }
    };
    FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy().withSleeper(sleeper);
    retryTemplate.setBackOffPolicy(backOffPolicy);
    retryTemplate.execute(new RetryCallback<Void, ResourceAccessException>() {
      @Override
      public Void doWithRetry(RetryContext retryContext) throws ResourceAccessException {
        LOG.debug(">RetryCount: {}", retryContext.getRetryCount());
        new RestTemplate().getForObject("https://unreachable.Host", String.class);
        return null;
      }
    });
  }
}

また、春の再試行による ExponentialBackOffPolicy もあります。

これがお役に立てば幸いです。

6

以下のコードのように使用できます。

@Retryable(exceptionExpression="#{@exceptionChecker.shouldRetry(#root)}",
  maxAttemptsExpression = "#{@integerFiveBean}",
  backoff = @Backoff(delayExpression = "#{1}", 
    maxDelayExpression = "#{5}", multiplierExpression = "#{1.1}"))
public void service3() {
  ...
}
3
Vikesh Royal