我的 spring-webflux 应用程序中有一个简单的控制器,如下所示,
@GetMapping("/ping")
suspend fun ping(): ResponseEntity<Map<String, Boolean>> {
println(coroutineContext)
waitforIO()
return ResponseEntity(mapOf("success" to true), HttpStatus.OK)
}
suspend fun waitforIO() {
println(coroutineContext)
delay(1000)
}
输出看起来像
[Context1{micrometer.observation={name=http.server.requests(null), error=null, context=name='http.server.requests', contextualName='null', error='null', lowCardinalityKeyValues=[exception='none', method='GET', outcome='SUCCESS', status='200', uri='UNKNOWN'], highCardinalityKeyValues=[http.url='/ping'], map=[class io.micrometer.core.instrument.LongTaskTimer$Sample='SampleImpl{duration(seconds)=0.066692583, duration(nanos)=6.6692583E7, startTimeNanos=475384383429625}', class io.micrometer.core.instrument.Timer$Sample='io.micrometer.core.instrument.Timer$Sample@4b6502a5'], parentObservation=null}}, MonoCoroutine{Active}@33bfeb7d, Dispatchers.Unconfined]
[Context1{micrometer.observation={name=http.server.requests(null), error=null, context=name='http.server.requests', contextualName='null', error='null', lowCardinalityKeyValues=[exception='none', method='GET', outcome='SUCCESS', status='200', uri='UNKNOWN'], highCardinalityKeyValues=[http.url='/ping'], map=[class io.micrometer.core.instrument.LongTaskTimer$Sample='SampleImpl{duration(seconds)=0.068251166, duration(nanos)=6.8251166E7, startTimeNanos=475384383429625}', class io.micrometer.core.instrument.Timer$Sample='io.micrometer.core.instrument.Timer$Sample@4b6502a5'], parentObservation=null}}, MonoCoroutine{Active}@33bfeb7d, Dispatchers.Unconfined]
有人可以详细说明一下为什么使用
Dispatchers.Unconfined
而不是Dispatchers.Default
吗? AFAIK,默认应该选择默认(显然!)。
我正在使用以下配置,如果这会在调试中发挥一些作用,
OpenJDK Runtime Environment JBR-17.0.7+7-985.2-nomod (build 17.0.7+7-b985.2)
kotlin("jvm") version "1.8.22"
kotlin("plugin.spring") version "1.8.22"
id("org.springframework.boot") version "3.1.5"
id("io.spring.dependency-management") version "1.1.3"
springCloudVersion="2022.0.4"
所有依赖项均由 spring-cloud-dependency 管理 - 2022.0.4.
Spring Webflux 默认使用
Unconfined
调度程序,尽管我不知道原因。
现在应该可以使用
CoWebFilter
更改调度程序,请参阅此问题。但是,您可能希望更新到 Spring Boot 3.2.1 以包含此附加修复。
我的猜测是基于修复该问题的提交(尽管我还没有亲自测试过这一点),您可以使用如下方式更改所有请求的调度程序:
@Component
class MyCoWebFilterWithContext : CoWebFilter() {
override suspend fun filter(exchange: ServerWebExchange, chain: CoWebFilterChain) {
withContext(Dispatchers.Default) {
chain.filter(exchange)
}
}
}