使用Spring WebFlux中的webclient在Mono上有条件地重复或重试 [英] Conditional repeat or retry on Mono with webclient from Spring WebFlux

查看:1028
本文介绍了使用Spring WebFlux中的webclient在Mono上有条件地重复或重试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做的是在带有webclient的Webflux中的Mono上有条件重复.情况如下:

What i want to do is a conditional repeat on a Mono in Webflux with webclient.The Situation is the following:

我们有一些商务休息服务服务,可返回生成的文档.该文档的生成是由在此服务之前被调用的另一服务触发的.但是,回到正题:文档生成服务需要10到30秒.我们要做的是:10秒钟后检查是否生成了文档(单声道).如果是这样,一切都很好.如果不是,请在5秒钟后重复(或重试)并检查是否生成了文档.依此类推,直到(最坏的情况)是30秒后超时.这可能吗?一些(伪)代码:

We have some business rest service service that returns a generated document. the generation of this document is triggered from another service that gets called before this one. But, back to business: the document generation service needs from 10-30 seconds. What we want to do is: check after 10 seconds if document (Mono) is generated. If so, all is fine. If not, repeat (or retry) after another 5 seconds and check if document is generated. And so on until (worst case) a timeout after 30 seconds. Is this possible? Some (pseudo) code:

return this.webClient.post().uri(SERVICE_URL)).        
body(BodyInserters.fromObject(docRequest)).retrieve().
bodyToMono(Document.class).
delaySubscription(Duration.ofSeconds(10)).
repeat5TimesWithDynamicTimeDelayUntil(!document.isEmpty()).
subscribe();

格里茨 贝尔纳多

推荐答案

是的,有可能.

Mono有两个用于重新订阅(因此可以重新触发请求)的概念

Mono has two concepts for re-subscribing (and thus, re-triggering the request)

  • retry =重新订阅上游是否已完成
  • 重复 =重新订阅上游是否成功完成
  • retry = re-subscribe if the upstream completed with an exception
  • repeat = re-subscribe if the upstream completed successfully

对于不同的用例,每个概念在Mono上都有多个重载方法.查找retry*repeat*方法. 例如,要无延迟地重试最大次数,请使用retry(int numRetries).

Each concept has multiple overloaded methods on Mono for different use cases. Look for the retry* and repeat* methods. For example, to retry a maximum number of times with no delay, use retry(int numRetries).

通过retryWhenrepeatWhen方法支持更复杂的用例,如以下示例所示.

More complex use cases are supported via the retryWhen and repeatWhen methods, as shown in the following examples.

要重试单声道是否异常完成最多5次,每次尝试之间间隔5秒:

To retry if the mono completed with an exception a maximum of 5 times with 5 seconds between each attempt:

// 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))

重试构建器支持其他退避策略(例如指数)和其他选项,以完全自定义重试.

The retry builder supports other backoff strategies (e.g. exponential) and other options to fully customize retries.

请注意,上面使用的retryWhen(Retry)方法已添加到反应堆核心v3.3.4.RELEASE中,并且已弃用retryWhen(Function)方法. 在反应堆核心v3.3.4.RELEASE之前,您可以使用

Note the retryWhen(Retry) method used above was added in reactor-core v3.3.4.RELEASE, and the retryWhen(Function) method was deprecated. Prior to reactor-core v3.3.4.RELEASE, you could use the retry function builder from reactor-extras project to create a Function to pass to retryWhen(Function).

如果需要成功重复一次,请使用.repeatWhen.repeatWhenEmpty代替上面的.retryWhen.

If you need to repeat on success, then use .repeatWhen or .repeatWhenEmpty instead of .retryWhen above.

使用 reactor-extras reactor-extras 项目,以创建重复Function,如下所示:

Use the repeat function builder from reactor-extras project to create the repeat Function as follows:

// 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))

如果要重新订阅成功或失败,也可以将.retry*.repeat*链接.

You can also chain a .retry* with a .repeat* if you want to re-subscribe on both success or failure.

这篇关于使用Spring WebFlux中的webclient在Mono上有条件地重复或重试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆