You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 05:36:05