Spring Boot 3.2 里用 WebClient 调上游 SSE,Controller 声明返回 Flux,前端却要等十几秒才一次性收到全部内容,抓包看到响应头没有 chunked,服务端日志显示上游读完之后才开始写响应。

一开始怀疑是「类路径上还有 Spring MVC 的依赖,WebFlux 没真正接管」,查了一圈,方向不对。

这类报错背后常见的原因有几处,逐个排除就行。中间某处调了 collectList 再返回,链路退化成一次性响应。还有一种是Controller 的返回类型写成了 ResponseEntity。

少数情况下是访问日志过滤器读了 body,把流提前消费掉了。

先检查返回类型里有没有聚合操作

grep -rn "collectList\|Flux<" src/main/java --include=*Controller.java

然后用 curl 看响应是否分块返回

curl -N -i http://localhost:8080/stream | head -20

去掉日志过滤器里对 body 的读取后重启

./mvnw -q spring-boot:run -Dspring-boot.run.arguments=--server.port=8080

等前面都确认过,再在入口确认传输编码

curl -sI http://localhost:8080/stream | grep -i transfer

别只看报错消失,验证要多做一步。第一个字节在 500ms 内到达,响应头带 Transfer-Encoding: chunked,前端逐字渲染而不是整段出现。

容易忽略的是,响应式链路里任何一次聚合操作都会把流退化成整体,排查时先看返回类型再看过滤器。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189