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

使用不同的URL重试Webflux Webclient

卫泉
2023-03-14

我正在使用webclient进行rest调用,我需要的是,如果主URL第n次失败,那么在次URL上进行下一次重试。请在下面找到我正在使用的逻辑的示例代码。但是似乎我们不能在client创建后更改URL,即使我更改了URL,它也不会生效,仍然会将请求激发到初始URL。

ClientHttpConnector connector;//initiate
WebClient webClient = WebClient.builder().clientConnector(connector).build();
WebClient.RequestBodyUriSpec client = webClient.post();

client.uri("http://primaryUrl/").body(BodyInserters.fromObject("hi")).retrieve().bodyToMono(String.class).retryWhen(Retry.anyOf(Exception.class)
                    .exponentialBackoff(Duration.ofSeconds(2), Duration.ofSeconds(10)).doOnRetry(x ->
                    {
                        if (x.iteration() == 2) {
                            client.uri("http://fail_over_url/");//this does not work
                        }
                    })
                    .retryMax(2)).subscribe(WebClientTest::logCompletion, WebClientTest::handleError);

有没有办法在重试周期中间更改URL?

共有1个答案

丌官嘉勋
2023-03-14

但似乎我们不能更改URL一旦他的客户机被创建

你不能-它是不变的。

即使我更改了URL也不会生效

实际上并没有更改URL。看看URI()方法-它返回一个带有URI集的新实例。由于您没有对这个新实例执行任何操作,因此没有发生任何事情(正如所预期的那样)

我可能建议的路径是创建一个单独的方法来形成并返回基本的WebClient发布服务器:

private Mono<String> fromUrl(String url) {
    return WebClient.builder().clientConnector(connector).build()
            .post()
            .body(BodyInserters.fromValue("hi"))
            .uri(url)
            .retrieve()
            .bodyToMono(String.class);
}

...然后执行以下操作:

fromUrl("https://httpstat.us/400").retryWhen(Retry.backoff(2, Duration.ofSeconds(1)))
        .onErrorResume(t -> Exceptions.isRetryExhausted(t), t -> fromUrl("https://httpstat.us/500").retryWhen(Retry.backoff(5, Duration.ofSeconds(1))))
        .onErrorResume(t -> Exceptions.isRetryExhausted(t), t -> fromUrl("https://httpstat.us/200").retryWhen(Retry.backoff(7, Duration.ofSeconds(1))))

...它将尝试/4003次,然后尝试/5005次,然后再尝试/200最多7次(但除非它已关闭,否则第一次尝试时当然会返回。)

请注意,上面的示例使用了最新版本的reactor-core,它内置了重试功能,而不是reactor Addons中的重试功能。将其转换为反应堆附加功能应该相当简单。

这并不是严格地在相同的重试周期中更改URL,而是将请求与每个请求的可配置重试链接在一起。这样,您就可以在不同的URL上设置不同的重试策略,如果您不一定希望重试从上一个点“继续”,这是有利的(例如,对于一个新的URL将回退设置为一秒是有意义的)

 类似资料:
  • 我是一个使用NIFI的大一新生。下面的NiFi dataflow从固定URL上的GET请求中获取数据,但是我的endpoint有一组参数来获取部分数据,例如页面ID。我希望避免为稍微不同的请求URL创建相同的工作流。 在API中,我可以请求可用的页面列表,我希望使用这样的请求的结果开始循环下面的工作流。我该怎么做??

  • 我有两个文件命名为文章和类别。我使用SEO URL结构生成了一个URL格式。样品: 实例com/文章标题 实例com/类别标题 代码: 但有一个问题。我不能同时使用两种url格式。htaccess文件。他看到第一行,但忽略了另一行。但是我想对这两个文件使用相同的格式。你能帮忙吗?

  • 我们有一个基于Spring的JUnit测试类,它利用一个内部测试上下文配置类 最近,服务类中引入了新的功能,相关测试应添加到ServiceTest中。但是,这也需要创建不同的测试上下文配置类(现有配置类的内部结构相当复杂,如果可能的话,将其更改为既服务于旧测试又服务于新测试似乎非常困难) 有没有一种方法可以实现一个测试类中的某些测试方法将使用一个配置类,而其他方法将使用另一个?似乎只适用于类级别,

  • 我有一个服务,可以将用户重定向到临时预签名的AWS下载。这些是大文件,通常为5-10GB。为了防止下载共享,我们有一个相对较短(30秒)的有效寿命。 原来,当我们注意到这个问题时,我们正在使用302找到临时重定向。一个小小的研究似乎表明我们应该使用307临时重定向。但是,这并不能解决wget的问题。对于笑和傻笑,我们尝试了303看其他,但这也不起作用。 有没有人知道get wget是如何重试原始U

  • 我想为同一个GET路径提供多个函数。 我也希望我的网络服务“找到”这些函数,当且仅当查询参数与URL字符串中的参数匹配时。 例如: 我有 对于该路径,我希望有2个功能: 和 现在我得到一个错误: 严重:在资源和/或提供程序类中检测到以下错误和警告:严重:产生媒体类型冲突。资源方法public javax . ws . RS . core . response 所以首先:有什么方法可以实现我在这里想

  • 例如: 数据提供程序1:dataA 数据提供程序2:dataB,dataC 数据提供程序3:dataD、dataE、dataG 所以我的测试需要一个数据提供者。但是我希望它根据测试组为不同的测试类型选择不同的数据提供者。例如,如果我正在运行“smoke”组,那么我希望使用数据提供者1;如果我正在运行“sanity”组,那么我希望运行数据提供者1和数据提供者2;如果我正在运行“regression”