当前位置: 首页 > 知识库问答 >
问题:

如何延迟重复的WebClient获取请求

长孙星汉
2023-03-14

我正在使用Spring5WebClient从RESTAPI重复获取运行进程的某些状态。

在这里的帮助下,我现在找到了这个解决方案:

webClient.get().uri(...).retrieve.bodyToMono(State.class)
          .repeat()
          .skipUntil(state -> stateFinished())
          .limitRequest(1)
          .subscribe(state -> {...});

在这种情况下,get请求以非常高的速率触发。什么是正确的方法来限制请求速率,让我们说每秒1个请求?

我尝试使用delayElements(Duration.ofSeconds(1)),但这只会延迟结果,而不会延迟请求本身。

共有3个答案

后阳炎
2023-03-14

您正在使用的delayElements告诉我您将它放在重复之后。您要延迟的是对WebClient的订阅。

webClient
      .get()
      .uri(...)
      .retrieve
      .bodyToMono(State.class)
      .delaySubscription(Duration.ofSeconds(1)) //Just add this before the repeat
      .repeat()
      .skipUntil(state -> stateFinished())
      .limitRequest(1)
      .subscribe(state -> {...});

这样做可以确保在第n个请求的响应和第n个请求的触发之间有第二次。如果您需要固定的呼叫频率,而不管每个请求响应的时间,请按照Roman的建议,用Flux.interval包装您的代码。

范成周
2023-03-14

在你的情况下,还有一个小的变通方法,你用一个通量作为限制器来压缩你的每个呼叫。

.zipWith(Flux.interval(Duration.of(1, ChronoUnit.SECONDS)))

虽然我认为delayElements()是有效的,但也许你没有把它放在WebClient堆栈的正确阶段。

赏成益
2023-03-14

您可以在自定义实现的配套的Publisher中使用重复时运算符

Mono.just("test")
        .repeatWhen(longFlux -> Flux.interval(Duration.ofSeconds(1)))
        .take(5)
        .log()
        .blockLast();

或者使用Reactor插件的Repeate功能

Mono.just("test")
        .repeatWhen(Repeat.times(Long.MAX_VALUE)
                .fixedBackoff(Duration.ofSeconds(1)))
        .take(5)
        .log()
        .blockLast();
 类似资料:
  • 我一直在学习spring Webflux和reactive programming,并陷入了一个问题,我试图解决的重试逻辑使用spring WebClient。我已经创建了一个客户机,并成功地调用了一个外部Web服务GETendpoint,该endpoint返回一些JSON数据。 当外部服务以状态响应时,响应包括标头,该标头具有一个值,指示在重试请求之前应等待多长时间。我想在spring WebF

  • 当我像这样定义和调用客户机方法时: 关于更多上下文:在我的例子中,我只希望在CacheFlux onCacheMissResume被触发时执行它:

  • 问题内容: 我正在尝试用Java做某事,而我需要一些东西在while循环中等待/延迟几秒钟。 我想构建一个步进音序器,并且对Java还是陌生的。有什么建议么? 问题答案: If you want to pause then use java.util.concurrent.TimeUnit: TimeUnit.SECONDS.sleep(1); TimeUnit.MINUTES.sleep(1);

  • Flask 的设计原则中有一条是响应对象被创建并在一条可能的回调链中传递,而在 这条回调链但中的任意一个回调,您都可以修改或者替换掉他们。当请求开始被 处理时,还没有响应对象,响应对象将在这一过程中,被某个视图函数或者系统 的其他组件按照实际需要来闯将。 但是,如果您想在响应过程的结尾修改响应对象,但是这是对象还不存在,那么会发生 什么呢?一个常见的例子是您可能需要在 before-request

  • 如何将转换为请求正文的表示形式?或者,如何正确地记录整个请求/响应,同时能够在其中散列潜在的凭据?

  • 问题内容: 我正在阅读有关go语言的延期声明。它允许您指定函数结束后要执行的操作。例如,如果您有文件指针或资源,而不是使用每个可能的返回路径编写自由/删除,则只需指定一次defer函数。 它看起来像一个模拟可能会转到C 最终(什么是C标准延迟/终结执行 ? ,会不会有范围后卫/范围退出成语?标准化在此之前,有什么意外讲的是一个对象,它这样做析构函数进行回调?看起来局部变量的析构函数顺序是理智的,并