Solución:
Con reactor-extra podrías hacerlo así:
.retryWhen(Retry.onlyIf(this::is5xxServerError)
.fixedBackoff(Duration.ofSeconds(10))
.retryMax(3))
private boolean is5xxServerError(RetryContext<Object> retryContext) {
return retryContext.exception() instanceof WebClientResponseException &&
((WebClientResponseException) retryContext.exception()).getStatusCode().is5xxServerError();
}
Actualizar:
Con la nueva API, la misma solución será:
.retryWhen(Retry.fixedDelay(3, Duration.ofSeconds(10))
.filter(this::is5xxServerError));
//...
private boolean is5xxServerError(Throwable throwable) {
return throwable instanceof WebClientResponseException &&
((WebClientResponseException) throwable).getStatusCode().is5xxServerError();
}
Puede hacer esto siguiendo el siguiente enfoque:
- Utilizar el
exchange()
método para obtener la respuesta sin una excepción, y luego lanzar una excepción específica (personalizada) en una respuesta 5xx (esto difiere deretrieve()
que siempre arrojaráWebClientResponseException
con un4xx
o5xx
estado); - Intercepte esta excepción específica en su lógica de reintento;
- Usar
reactor-extra
– contiene una forma agradable de usarretryWhen()
para reintentos más complejos y específicos. Luego, puede especificar un reintento de retroceso aleatorio que comienza después de 10 segundos, llega a un tiempo arbitrario y lo intenta un máximo de 3 veces. (O puede usar los otros métodos disponibles para elegir una estrategia diferente, por supuesto).
Por ejemplo:
//...webclient
.exchange()
.flatMap(clientResponse -> {
if (clientResponse.statusCode().is5xxServerError()) {
return Mono.error(new ServerErrorException());
} else {
//Any further processing
}
}).retryWhen(
Retry.anyOf(ServerErrorException.class)
.randomBackoff(Duration.ofSeconds(10), Duration.ofHours(1))
.maxRetries(3)
)
);
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)