有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用不同的URL重试java Webflux Webclient

我正在使用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) 个答案

  1. # 1 楼答案

    But it seems we cannot change the URL once he client is created

    你不能——它是不可变的

    even if i change the URL its not getting effected

    您实际上并没有更改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中的重试功能。将其转换为reactor插件功能应该相当简单

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