You need to enable JavaScript to run this app. Spring WebFlux消费SSE触发io.netty ReadTimeoutException如何保持长连接
优惠活动
大模型
产品
解决方案
定价
更多

Spring WebFlux消费SSE触发io.netty ReadTimeoutException如何保持长连接

Spring WebFlux SSE客户端长连接超时断开解决方案

问题根因

你遇到的ReadTimeoutException是WebClient底层Netty组件的默认读超时配置导致的:默认规则为60秒未读取到任何网络数据时,主动断开连接,该规则不适用于推送时机随机的SSE长连接场景。

可行解决方案

方案1:自定义WebClient禁用读超时

直接修改WebClient的底层HttpClient配置,移除默认的读超时限制,适配SSE长连接场景,代码如下:

import io.netty.handler.timeout.ReadTimeoutHandler;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;

// 构建无读超时的HttpClient
HttpClient httpClient = HttpClient.create()
        .doOnConnected(conn -> conn.removeHandler(ReadTimeoutHandler.class));

// 用自定义HttpClient构建WebClient实例
WebClient customWebClient = WebClient.builder()
        .clientConnector(new ReactorClientHttpConnector(httpClient))
        .build();

原有业务消费代码无需修改,替换为上述自定义的WebClient实例即可。

方案2:增加自动重试机制(推荐配合使用)

如果不想完全禁用读超时(避免真的出现连接假死无法感知),可以在消费逻辑中增加异常重试规则,触发超时后自动重连:

import org.springframework.web.reactive.function.client.WebClientRequestException;
import io.netty.handler.timeout.ReadTimeoutException;
import reactor.util.retry.Retry;
import java.time.Duration;

customWebClient.get()
        .uri("http://localhost:8080/events")
        .accept(MediaType.TEXT_EVENT_STREAM)
        .retrieve()
        .bodyToFlux(type)
        // 仅针对读超时异常进行无限次1秒间隔重试,可根据需求调整重试次数和间隔
        .retryWhen(Retry.fixedDelay(Long.MAX_VALUE, Duration.ofSeconds(1))
                .filter(e -> e instanceof WebClientRequestException 
                        && e.getCause() instanceof ReadTimeoutException))
        .subscribe(event -> process(event));

方案3:服务端增加SSE心跳(协议层面最优)

如果有权限调整服务端逻辑,可让服务端每隔30秒发送一条SSE注释行(格式为: 心跳内容)作为心跳包,这类注释不会被客户端识别为业务事件,同时能保证有持续数据传输,无需修改客户端超时配置就能避免超时断开,稳定性最高。

注意事项

  • 单独禁用读超时的场景下,如果服务端出现异常导致连接假死,客户端会长期持有无效连接,建议配合重试机制或服务端心跳使用。

内容的提问来源于stack exchange,提问作者Arun Kumar V

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 15:06:04