WebClient发送重复请求问题:为何代码每次调用会发送两次请求?
WebClient重复请求问题分析
核心原因
这段代码里的accepted是一个Flux<Boolean>,而Reactor框架中的Flux/Mono属于冷序列——冷序列的特性是每次发起订阅都会从头触发整个数据流的执行。
在你的代码中:
- 第一次订阅:调用
accepted.subscribe { ... },触发WebClient发送第一次请求,拿到响应后执行日志打印。 - 第二次订阅:调用
accepted.awaitSingle()(Kotlin协程挂起函数,本质也是订阅操作),再次触发WebClient发送第二次请求,获取响应后返回结果。
两次独立的订阅直接导致了重复请求。
解决方案
方案1:将冷序列转为热序列共享请求结果
通过share()或cache()操作符把冷序列转换成热序列,让多次订阅复用同一次请求的响应:
suspend fun requestSimulation(simulationRequest: SimulationRequest): Boolean { val accepted = WebClient.create(simulationServiceHost) .post() .uri(simulationEndpoint) .bodyValue(simulationRequest) .retrieve() .bodyToFlux(Boolean::class.java) .share() // 共享订阅,仅发起一次请求 accepted.subscribe { bool: Boolean -> logger.info(bool.toString()) } return accepted.awaitSingle() }
方案2:仅订阅一次,合并日志与结果处理
既然返回的是单个Boolean值,用bodyToMono替代bodyToFlux更贴合场景,同时通过doOnSuccess在单次订阅中处理日志逻辑:
suspend fun requestSimulation(simulationRequest: SimulationRequest): Boolean { return WebClient.create(simulationServiceHost) .post() .uri(simulationEndpoint) .bodyValue(simulationRequest) .retrieve() .bodyToMono(Boolean::class.java) .doOnSuccess { bool -> logger.info(bool.toString()) } .awaitSingle() }
内容的提问来源于stack exchange,提问作者Jahan Zinedine
相关产品推荐
相关产品推荐

