Spring 5的Reactive WebClient不是那么异步吗?
Spring 5's Reactive WebClient not so asyncronous?
我遇到了奇怪的 Spring WebClient 的行为。我有两个 URLs,慢的和快的。 Bot 什么都不做,但速度很慢,只需等待十秒钟即可响应。当我使用 WebClient 同时调用它们时,我预计 fast URL 将比 slow 更早完成,但实际上它们同时完成。最糟糕的是 - 有时它会按预期工作。有没有人有想法,为什么它以这种方式行事,以及如何使其正常工作?这是我的例子
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
下面非常简单的测试表明 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();
}
我遇到了奇怪的 Spring WebClient 的行为。我有两个 URLs,慢的和快的。 Bot 什么都不做,但速度很慢,只需等待十秒钟即可响应。当我使用 WebClient 同时调用它们时,我预计 fast URL 将比 slow 更早完成,但实际上它们同时完成。最糟糕的是 - 有时它会按预期工作。有没有人有想法,为什么它以这种方式行事,以及如何使其正常工作?这是我的例子
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
下面非常简单的测试表明 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();
}