Spring WebClient 正在阻塞线程
Spring WebClient is blocking the thread
Spring WebClient 应该是非阻塞的 (reference doc)。但是当我在示例演示代码中尝试时,它阻塞了主线程。
当我 运行 下面的代码时,我得到以下输出:
main: main
runBlocking: main
async: main
304 //length of output
wait over in 2346
after async
我原以为“after async”会在“304”(API 调用的输出)之前打印,因为 API 不应该阻塞主线程并且 main() 函数应该继续使用异步块之后的代码。
主要代码::
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.springframework.http.client.reactive.ReactorClientHttpConnector
import org.springframework.web.reactive.function.client.WebClient
import reactor.netty.http.client.HttpClient
import kotlin.system.measureTimeMillis
fun main() {
val httpClient = HttpClient.create()
val client: WebClient = WebClient.builder()
.baseUrl("https://postman-echo.com/get?foo1=bar1&foo2=bar2")
.clientConnector(ReactorClientHttpConnector(httpClient))
.build()
println("main: " + Thread.currentThread().name)
runBlocking {
println("runBlocking: " + Thread.currentThread().name)
async {
println("async: " + Thread.currentThread().name)
val time = measureTimeMillis {
val out = client.get().retrieve().bodyToMono(String::class.java).block()
println(out.length)
}
println("wait over in $time")
}
delay(1)
println("after async")
}
}
考虑使用 .awaitBody<T>()
而不是 .block()
(这是阻塞操作)
类似于:
val out = client.get().retrieve().awaitBody<String>()
Spring WebClient 应该是非阻塞的 (reference doc)。但是当我在示例演示代码中尝试时,它阻塞了主线程。
当我 运行 下面的代码时,我得到以下输出:
main: main
runBlocking: main
async: main
304 //length of output
wait over in 2346
after async
我原以为“after async”会在“304”(API 调用的输出)之前打印,因为 API 不应该阻塞主线程并且 main() 函数应该继续使用异步块之后的代码。
主要代码::
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.springframework.http.client.reactive.ReactorClientHttpConnector
import org.springframework.web.reactive.function.client.WebClient
import reactor.netty.http.client.HttpClient
import kotlin.system.measureTimeMillis
fun main() {
val httpClient = HttpClient.create()
val client: WebClient = WebClient.builder()
.baseUrl("https://postman-echo.com/get?foo1=bar1&foo2=bar2")
.clientConnector(ReactorClientHttpConnector(httpClient))
.build()
println("main: " + Thread.currentThread().name)
runBlocking {
println("runBlocking: " + Thread.currentThread().name)
async {
println("async: " + Thread.currentThread().name)
val time = measureTimeMillis {
val out = client.get().retrieve().bodyToMono(String::class.java).block()
println(out.length)
}
println("wait over in $time")
}
delay(1)
println("after async")
}
}
考虑使用 .awaitBody<T>()
而不是 .block()
(这是阻塞操作)
类似于:
val out = client.get().retrieve().awaitBody<String>()