Реактивный веб-клиент Spring 5 не такой асинхронный?

Я встретил странное поведение Spring WebClient. У меня два URL-адреса, медленный и быстрый. Бот ничего не делает, а просто подождите десять секунд до ответа. Когда я вызываю их одновременно с помощью WebClient, я ожидаю, что быстрый URL-адрес будет завершен раньше, чем медленный, но на самом деле они оба завершились одновременно. И что хуже всего - иногда это работает так, как ожидалось. Есть ли у кого-нибудь мысли, почему он действует таким образом и как заставить его работать правильно? Вот мой пример

fun main() {
    val webClient = WebClient.create()
    println("${LocalDateTime.now()} [${Thread.currentThread().name}] Start")

    webClient.get().uri("http://callback-mock/slow-url").exchange()
       .subscribe { response -> 
            println("${LocalDateTime.now()} [${Thread.currentThread().name}] Executed callback slow URL with result ${response.statusCode()}") 
       }
    webClient.get().uri("http://callback-mock/fast-url").exchange()
       .subscribe { response -> 
            println("${LocalDateTime.now()} [${Thread.currentThread().name}] Executed callback fast URL with result ${response.statusCode()}")
       }
    println("${LocalDateTime.now()} [${Thread.currentThread().name}] Waiting for exit")
    Thread.sleep(15_000)
    println("${LocalDateTime.now()} [${Thread.currentThread().name}] Exit")
}

Результат (в большинстве случаев)

2019-10-02T13:04:34.536 [main] Start
2019-10-02T13:04:35.173 [main] Waiting for exit
2019-10-02T13:04:44.791 [reactor-http-nio-4] Executed callback slow URL with result 200 OK
2019-10-02T13:04:44.791 [reactor-http-nio-2] Executed callback fast URL with result 200 OK
2019-10-02T13:04:50.193 [main] Exit

Process finished with exit code 0

В редких случаях работает как положено

2019-10-02T13:23:35.619 [main] Start
2019-10-02T13:23:36.300 [main] Waiting for exit
2019-10-02T13:23:36.802 [reactor-http-nio-2] Executed callback fast URL with result 200 OK
2019-10-02T13:23:45.810 [reactor-http-nio-4] Executed callback slow URL with result 200 OK
2019-10-02T13:23:51.308 [main] Exit

Process finished with exit code 0

person Alexey Sviridov    schedule 02.10.2019    source источник


Ответы (1)


Следующий очень простой тест показывает, что fast всегда возвращается первым. (Reactor Netty используется как HTTP-сервер)

    @Test
    public void test() throws InterruptedException {
        DisposableServer server =
                HttpServer.create()
                        .port(0)
                        .route(r -> r.get("/fast", (req,res) -> res.sendString(Mono.just("test")))
                                    .get("/slow", (req,res) -> res.sendString(Mono.just("test").delayElement(Duration.ofSeconds(10)))))
                        .bindNow();

        WebClient webClient = WebClient.create();
        System.out.println(LocalDateTime.now() + " " + Thread.currentThread().getName() + " Start");

        webClient.get().uri("http://localhost:" + server.port() + "/slow").exchange()
                .subscribe(response ->
                        System.out.println(LocalDateTime.now() + " " + Thread.currentThread().getName() +
                                " Executed callback slow URL with result " + response.statusCode()));

        webClient.get().uri("http://localhost:" + server.port() + "/fast").exchange()
                .subscribe(response ->
                        System.out.println(LocalDateTime.now() + " " + Thread.currentThread().getName() +
                                " Executed callback fast URL with result " + response.statusCode()));

        System.out.println(LocalDateTime.now() + " " + Thread.currentThread().getName() + " Waiting for exit");
        Thread.sleep(15_000);
        System.out.println(LocalDateTime.now() + " " + Thread.currentThread().getName() + " Exit");

        server.disposeNow();
    }
person Violeta Georgieva    schedule 04.10.2019
comment
Хм ... возможно вы правы, может что-то не так с mock server ... Я проверю и отмечу ваш ответ, если он - person Alexey Sviridov; 05.10.2019
comment
Вы абсолютно правы, большое вам спасибо. Это была проблема на сервере python, он работал в однопоточном режиме. Спасибо за правильное направление! - person Alexey Sviridov; 07.10.2019