浅谈Spring Cloud Gateway 转发 SSE 的那些坑

 更新时间:2026年06月02日 09:31:53   作者:go 码头整点薯条  
本文主要介绍了SSE在Gateway场景下的常见问题题并提供了解决方案,包括禁止响应缓存、正确配置超时设置、透传Header等确保Gateway不加工SSE流式响应,帮助开发者避免常见错误

—— 为什么你本地能流,一上网关就“卡死”

一、背景:SSE 本地好好的,上了 Gateway 全废了

在做 AI 问答流式输出时,我最初的架构是这样的:

Browser
  ↓
Spring Cloud Gateway
  ↓
AI Service(SSE)

现象非常诡异:

  • 直连 AI 服务:✅ 一边生成一边返回
  • 走 Gateway:❌ 页面一直 loading
  • 最后一次性返回,或者直接超时

当时的第一反应是:

“是不是 SSE 不能过网关?”

结论是:

SSE 可以过 Gateway,但默认配置下,几乎一定会翻车

二、SSE 在 Gateway 场景下到底“特殊”在哪?

1️⃣ SSE 的几个关键特性

  • 长连接
  • 响应体是持续写入
  • 没有 Content-Length
  • 依赖 Transfer-Encoding: chunked

而 Gateway 的本质是:

一个“智能代理” + 各种 Filter

这就产生了天然冲突。

三、第一个坑:响应被 Gateway “缓存”了

❌ 错误表现

  • AI 服务已经在流式返回
  • Gateway 一直等
  • 最后一次性吐给客户端

❌ 根本原因

Gateway 默认会尝试:

  • 聚合 response body
  • 处理后再返回
  • 破坏了 SSE 的“边写边发”

✅ 正确做法:禁止响应缓存

spring:
  cloud:
    gateway:
      httpclient:
        response-timeout: 0s

并且不要使用这些 Filter:

  • ModifyResponseBody
  • RewriteResponseBody
  • CacheRequestBody

👉 这些 Filter 天生会吃掉流

四、第二个坑:超时设置会“悄悄杀死连接”

❌ 常见错误配置

spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 5000
        response-timeout: 30s

对普通接口没问题
对 SSE 来说是 致命的

原因

  • SSE 是“永不结束的响应”
  • Gateway 会认为:

“30 秒还没结束?那我关了”

✅ SSE 专用超时配置

spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 5000
        response-timeout: 0s   # 关键

五、第三个坑:Header 被 Gateway “改坏了”

❌ 错误现象

  • 前端 EventSource 连不上
  • 或连接成功但不触发 onmessage

常见罪魁祸首

❌ Content-Type 被改写

Content-Type: application/json 

而不是:

text/event-stream 

✅ Gateway 必须“原样透传”

spring:
  cloud:
    gateway:
      default-filters:
        - PreserveHostHeader

并且不要在 Filter 里手动 set header。

六、第四个坑:HTTP/1.1 被无意中升级成 HTTP/2

问题表现

  • 某些客户端收不到流
  • 特别是 EventSource

原因

  • HTTP/2 对流量有额外 buffering
  • 某些浏览器 / 代理对 SSE + H2 支持不好

✅ 强制 Gateway 使用 HTTP/1.1

spring:
  cloud:
    gateway:
      httpclient:
        protocol: HTTP11

七、一个「能跑通 SSE 的 Gateway 路由示例」

spring:
  cloud:
    gateway:
      routes:
        - id: ai-sse
          uri: lb://mb-ai
          predicates:
            - Path=/ai/health_manager/stream
          filters:
            - StripPrefix=1

关键点总结:

  • 不改 response body
  • 不缓存
  • 不超时
  • 不动 header

八、前端为什么“必须立即有输出”?

很多人忽略了这一点。

SSE 的一个隐形规则

如果服务端迟迟不发送第一条 data,浏览器会以为连接失败

建议做法

AI 服务端:

emitter.send(" "); // 先发一个空事件 

Gateway 才会立刻把连接“刷”给客户端。

九、排查 SSE 在 Gateway 卡死的 checklist

当你遇到“能连但不流”的情况,按顺序查:

  • Gateway response-timeout 是否为 0
  • 是否使用了 ModifyResponseBody
  • Content-Type 是否是 text/event-stream
  • 是否被 HTTP/2 代理
  • AI 是否第一时间发送 data
  • 是否被 nginx 二次代理缓冲

十、我的最终经验总结

SSE 在 Gateway 下不是“配置问题”,而是“思维问题”

你必须接受:

  • SSE 不是一个“普通 HTTP 响应”
  • Gateway 不应该“加工它”
  • 它只应该当一根“水管”

一旦你试图:

  • 解析
  • 缓存
  • 重写

👉 流式必死。

十一、什么时候我会“绕开 Gateway”?

说一句大实话:

  • 超高频 AI 流
  • 大并发长连接
  • 对延迟极敏感

👉 我会让前端直连 AI 服务

Gateway 只做:

  • 鉴权
  • 路由发现

十二、写在最后

如果你在做:

  • AI 对话
  • ChatGPT 类应用
  • 实时推送

那你迟早会和 SSE + Gateway 正面交锋。

到此这篇关于浅谈Spring Cloud Gateway 转发 SSE 的那些坑的文章就介绍到这了,更多相关Spring Cloud Gateway 转发 SSE内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java构建菜单树的实现示例

    Java构建菜单树的实现示例

    本文主要介绍了Java构建菜单树的实现示例,像一级菜单,二级菜单,三级菜单甚至更多层级的菜单,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • java学习之一维数组中重复元素的去除

    java学习之一维数组中重复元素的去除

    关于一维数组中有重复的元素该怎么剔除,作为java初学者的我整理出不调用任何特殊库的基础方法,这种思想在其他语言也适用,有需要的朋友可以借鉴参考下
    2021-09-09
  • java Spring的启动原理详解

    java Spring的启动原理详解

    大家好,本篇文章主要讲的是java Spring的启动原理详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • 不同Java泛型构造函数的详解

    不同Java泛型构造函数的详解

    这篇文章主要介绍了不同Java泛型构造函数的详解,因为对象是应用类型,对象赋值是指向同一个对象,所以如果需要保存对象某个时刻的状态,就需要构造函数来new一个新的对象。下面我们来详细了解一下吧
    2019-06-06
  • Java利用WatchService监听文件变化示例

    Java利用WatchService监听文件变化示例

    本篇文章主要介绍了Java利用WatchService监听文件变化示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • java反射使用示例分享

    java反射使用示例分享

    这篇文章主要介绍了java反射使用示例,代码很简单,需要的朋友可以参考下
    2014-02-02
  • 深入了解Java File分隔符和Path分隔符的使用

    深入了解Java File分隔符和Path分隔符的使用

    不同的操作系统使用不同的字符作为文件和路径分隔符。当我们的应用程序需要在多个平台上运行时,我们需要正确处理这些问题。Java帮助我们选择一个合适的分隔符,本文就来聊聊Java中File分隔符和 Path分隔符的使用
    2022-07-07
  • Zuul实现服务网关路由全过程

    Zuul实现服务网关路由全过程

    文章介绍了微服务架构中路由层的作用,Spring Cloud Zuul作为Netflix的动态路由和负载均衡器,虽有Zuul 2,但Spring Cloud Gateway已成为更推荐的网关方案,强调路由层的高可用性对系统稳定性至关重要
    2025-07-07
  • 修改Android应用的样式的一些关键点解析

    修改Android应用的样式的一些关键点解析

    这篇文章主要介绍了修改Android应用的样式的一些关键点,即对影响外观的theme跟style的相关修改,需要的朋友可以参考下
    2015-12-12
  • SpringBoot2 Jpa 批量删除功能的实现

    SpringBoot2 Jpa 批量删除功能的实现

    这篇文章主要介绍了SpringBoot2 Jpa 批量删除功能的实现,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01

最新评论