1 回答
TA贡献1884条经验 获得超4个赞
对的,这是可能的。
Mono
有两个重新订阅的概念(因此,重新触发请求)
retry = 如果上游完成异常,则重新订阅
如果上游成功完成, repeat = 重新订阅
每个概念都有Mono
针对不同用例的多个重载方法。寻找retry*
和repeat*
方法。例如,要无延迟地重试最大次数,请使用retry(int numRetries)
.
retryWhen
通过和方法支持更复杂的用例repeatWhen
,如以下示例所示。
重试时
如果单声道以异常完成最多 5 次,每次尝试之间间隔 5 秒,则重试:
// From reactor-core >= v3.3.4.RELEASE import reactor.util.retry.Retry;this.webClient .post() .uri(SERVICE_URL) .body(BodyInserters.fromValue(docRequest)) .retrieve() .bodyToMono(Document.class) .retryWhen(Retry.fixedDelay(5, Duration.ofSeconds(5))) .delaySubscription(Duration.ofSeconds(10))
重试构建器支持其他退避策略(例如指数)和其他选项以完全自定义重试。
请注意,retryWhen(Retry)
上面使用的方法是在 reactor-core v3.3.4.RELEASE 中添加的,并且该retryWhen(Function)
方法已被弃用。在 reactor-core v3.3.4.RELEASE 之前,您可以使用reactor-extras项目中的重试函数构建器来创建一个Function
传递给retryWhen(Function)
.
重复时
如果您需要在成功时重复,请使用.repeatWhen
or.repeatWhenEmpty
而不是.retryWhen
上面的。
使用reactor-extras项目中的repeat 函数构建器来创建repeat Function
,如下所示:
// From reactor-extras
import reactor.retry.Repeat;
this.webClient
.post()
.uri(SERVICE_URL)
.body(BodyInserters.fromValue(docRequest))
.retrieve()
.bodyToMono(Document.class)
.filter(document -> !document.isEmpty())
.repeatWhenEmpty(Repeat.onlyIf(repeatContext -> true)
.exponentialBackoff(Duration.ofSeconds(5), Duration.ofSeconds(10))
.timeout(Duration.ofSeconds(30)))
.delaySubscription(Duration.ofSeconds(10))
如果您想在成功或失败时重新订阅,也可以将 a.retry*与 a链接。.repeat*
添加回答
举报