8

sto leggendo su GCM: https://developers.google.com/cloud-messaging/serverPrimavera RestTemplate: subentro esponenziale riprovare politica

e uno dei requisiti è che il server deve essere in grado di:

  • gestire le richieste e inviare di nuovo utilizzando back-off esponenziale.

Uso Spring RestTemplate per il mio back-end che proviene da Spring Boot. Non sembra essere un metodo che posso utilizzare per impostare la mia politica di riprova nei documenti: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

Anche quando ho cercato su Google, ho trovato il RetryTemplate, ma fa parte di Spring Batch e non estende RestTemplate che mi fa pensare che non dovrebbe essere usato per operazioni di Rest, ma piuttosto operazioni Spring Batch come l'elaborazione di grandi quantità di transazioni: http://docs.spring.io/spring-batch/2.1.x/apidocs/org/springframework/batch/retry/support/RetryTemplate.html

C'è un modo per utilizzare il backoff esponenziale con Spring RestTemplate?

+3

https://github.com/rholder/guava-retrying ha una strategia di backoff esponenziale. È un sistema di asciugatura generale flessibile, che puoi utilizzare per riprovare tutto ciò che desideri. –

+1

È possibile aggiungere un nuovo tentativo come dipendenza per gestire Riprova https://github.com/spring-projects/spring-retry. –

+1

Abbiamo tale implementazione nel framework principale per il supporto JMS. Questa è un'idea interessante. Potresti creare un problema [nel tracker dei problemi di Spring Framework] (https://jira.spring.io/browse/SPR)? Grazie! –

risposta

5

Buona giornata!

Immagino che il comportamento desiderato possa essere raggiunto implementando la classe personalizzata Sleeper.

Dopodiché è necessario impostare questo dormiente a BackOffPolicy come segue:

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

Inoltre v'è ExponentialBackOffPolicy entro la primavera-retry.

Spero che questo possa essere d'aiuto.