Spring Webclient 重试并在所有重试都用完后执行代码
Spring Webclient retry and execute a code if all retries are exhausted
我有一个 webhook 服务,可以将事件发送到不同的源 (URLs)。按照设计,请求超时为10s,如果失败,重试3次。如果所有重试都失败,则必须执行代码以禁用数据库中的 URL。
到目前为止,我成功重试并延迟了 5 秒。但是,我不确定失败后如何执行代码。
try{
String body = objectMapper.writeValueAsString(webhookDTO);
webClient.post()
.uri(webhook.getUrl())
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(body)
.exchange()
.timeout(Duration.ofSeconds(5))
.retryWhen(Retry.backoff(3, Duration.ofSeconds(5))
.jitter(0d)
.doAfterRetry(retrySignal -> {
logger.info("Retried " + retrySignal.totalRetries());
})
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal)
-> new WebhookTimeoutException()))
.doOnSuccess(clientResponse -> {
logger.info("Event is received by " + client);
})
.subscribe();
} catch (Exception e) {
logger.error("Error on webhook dispatcher: ", e);
}
谁能举例说明如何做到这一点?
你快到了!只需使用 doOnError
,如此处所示。这里的思路,一旦全部尝试失败,你就抛WebhookTimeoutException
。仅当抛出错误并更新数据库时才调用 doOnError。例外 class 是可选的。你可以忽略它。
webClient.post()
.uri(webhook.getUrl())
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(body)
.exchange()
.timeout(Duration.ofSeconds(5))
.retryWhen(Retry.backoff(3, Duration.ofSeconds(5))
.jitter(0d)
.doAfterRetry(retrySignal -> {
logger.info("Retried " + retrySignal.totalRetries());
})
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal)
-> new WebhookTimeoutException()))
.doOnSuccess(clientResponse -> {
logger.info("Event is received by " + client);
})
.doOnError(WebhookTimeoutException.class, (msg) -> {
System.out.println("Message :: " + msg);
// here update the DB
dbRepository.save(...);
})
.subscribe();
我有一个 webhook 服务,可以将事件发送到不同的源 (URLs)。按照设计,请求超时为10s,如果失败,重试3次。如果所有重试都失败,则必须执行代码以禁用数据库中的 URL。
到目前为止,我成功重试并延迟了 5 秒。但是,我不确定失败后如何执行代码。
try{
String body = objectMapper.writeValueAsString(webhookDTO);
webClient.post()
.uri(webhook.getUrl())
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(body)
.exchange()
.timeout(Duration.ofSeconds(5))
.retryWhen(Retry.backoff(3, Duration.ofSeconds(5))
.jitter(0d)
.doAfterRetry(retrySignal -> {
logger.info("Retried " + retrySignal.totalRetries());
})
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal)
-> new WebhookTimeoutException()))
.doOnSuccess(clientResponse -> {
logger.info("Event is received by " + client);
})
.subscribe();
} catch (Exception e) {
logger.error("Error on webhook dispatcher: ", e);
}
谁能举例说明如何做到这一点?
你快到了!只需使用 doOnError
,如此处所示。这里的思路,一旦全部尝试失败,你就抛WebhookTimeoutException
。仅当抛出错误并更新数据库时才调用 doOnError。例外 class 是可选的。你可以忽略它。
webClient.post()
.uri(webhook.getUrl())
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(body)
.exchange()
.timeout(Duration.ofSeconds(5))
.retryWhen(Retry.backoff(3, Duration.ofSeconds(5))
.jitter(0d)
.doAfterRetry(retrySignal -> {
logger.info("Retried " + retrySignal.totalRetries());
})
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal)
-> new WebhookTimeoutException()))
.doOnSuccess(clientResponse -> {
logger.info("Event is received by " + client);
})
.doOnError(WebhookTimeoutException.class, (msg) -> {
System.out.println("Message :: " + msg);
// here update the DB
dbRepository.save(...);
})
.subscribe();