web-dev-qa-db-fra.com

Réessayez la requête HTTP Java RestTemplate si l'hôte est hors ligne.

Bonjour, J'utilise la variable printemps RestTemplate pour appeler une API REST. L'API peut être très lente ou même hors ligne. Mon application construit le cache en envoyant des milliers de requêtes les unes après les autres. Les réponses peuvent également être très lentes car elles contiennent beaucoup de données.

J'ai déjà augmenté le délai d'attente à 120 secondes. Mon problème maintenant, c'est que l'API peut être hors ligne et j'obtiens une exception org.Apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool.

Dans le cas où l'API est hors ligne, l'application doit attendre et essayer jusqu'à ce que l'API soit à nouveau en ligne.

Puis-je atteindre cet objectif dans RestTemplate out of the box sans créer moi-même des boucles d'exception?

Merci!

7
Robert Moszczynski

Utilisez Spring Retry project ( https://dzone.com/articles/spring-retry-ways-integrate , https://github.com/spring-projects/spring-retry ).

Il est conçu pour résoudre des problèmes comme le vôtre.

7
Rafal G.

J'ai eu la même situation et fait quelques recherches sur Google a trouvé la solution. Donner la réponse dans l'espoir d'aider quelqu'un d'autre. Vous pouvez définir l’essai maximal et l’intervalle de temps pour chaque essai.

@Bean
  public RetryTemplate retryTemplate() {

    int maxAttempt = Integer.parseInt(env.getProperty("maxAttempt"));
    int retryTimeInterval = Integer.parseInt(env.getProperty("retryTimeInterval"));

    SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
    retryPolicy.setMaxAttempts(maxAttempt);

    FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
    backOffPolicy.setBackOffPeriod(retryTimeInterval); // 1.5 seconds

    RetryTemplate template = new RetryTemplate();
    template.setRetryPolicy(retryPolicy);
    template.setBackOffPolicy(backOffPolicy);

    return template;
  }

Et mon service de repos que je veux exécuter est ci-dessous.

retryTemplate.execute(context -> {
        System.out.println("inside retry method");
        ResponseEntity<?> requestData = RestTemplateProvider.getInstance().postAsNewRequest(bundle, ServiceResponse.class, serivceURL,
                CommonUtils.getHeader("APP_Name"));

        _LOGGER.info("Response ..."+ requestData);
            throw new IllegalStateException("Something went wrong");
        });
6
Devender Kumar

Vous pouvez également vous attaquer à cette annotation en utilisant Spring Retry. De cette façon, vous éviterez d'implémenter le modèle.

Ajoutez-le à votre pom.xml

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.1.2.RELEASE</version>
</dependency>

Activez-le pour votre application/configuration

@SpringBootApplication
@EnableRetry
public class MyApplication {
  //...
}

Méthodes de protection menacées d’échec avec @Retryable

@Service
public class MyService {

  @Retryable(maxAttempts=5, value = RuntimeException.class, 
             backoff = @Backoff(delay = 15000, multiplier = 2))
  public List<String> doDangerousOperationWithExternalResource() {
     // ...
  }

}
0
cheffe