spring cloud gateway 必须显式配置 ws:// 或 wss:// 协议路由,uri 不可为 http://,需匹配 upgrade 头、避免 stripprefix,建议直连或 lb:ws:// 并确保后端正确处理 websocket 握手。

Spring Cloud Gateway 默认不自动代理 WebSocket 请求,必须显式配置 ws:// 或 wss:// 协议的路由,否则客户端连接会立即断开,报 java.lang.UnsupportedOperationException 或 404/503。
WebSocket 路由必须用 ws:// 或 wss:// 协议写死 uri
Gateway 不会把 http:// 自动升级为 WebSocket,也不能靠过滤器“改协议”。uri 字段必须明确以 ws:// 或 wss:// 开头,否则请求会被当作普通 HTTP 处理,触发协议不匹配错误。
-
uri: http://backend:8080→ ❌ 一定失败,即使后端支持 WebSocket -
uri: ws://backend:8080→ ✅ 正确,直连模式 -
uri: lb:ws://message-service→ ✅ 正确,服务发现模式(需启用spring.cloud.gateway.discovery.locator.enabled=true) -
uri: lb://message-service→ ❌ 协议缺失,Gateway 不识别为 WebSocket 流量
Path 断言要匹配 Upgrade 请求头,不能只靠路径
WebSocket 握手本质是 HTTP GET + Upgrade: websocket 头。Gateway 的 Path 断言只校验路径,但后端服务可能依赖完整路径(如 /ws/{userId})。如果目标服务要求路径带参数或固定前缀,StripPrefix 过滤器不能用于 WebSocket 路由——它会破坏 Sec-WebSocket-Key 等关键头,导致握手失败。
通过Gate-Info和Gate-News MCP进行宏观驱动的加密货币分析,用于CPI、NFP、美联储、利率、工资等宏观因素与加密货币、日历或指标的关联。
- ✅ 推荐写法:
- Path=/ws/**,后端监听/ws路径,不依赖 StripPrefix - ❌ 避免写法:
- Path=/api/ws/**+StripPrefix=2→ 可能丢掉必要路径段或干扰头 - ⚠️ 注意:某些旧版 Spring Boot(如 2.7.x)对带查询参数的 WebSocket 路径支持不稳定,建议路径尽量简洁,参数改用连接后消息体传递
生产环境必须加 SetResponseHeader 过滤器
部分客户端(尤其是浏览器)在收到响应时,会对 Sec-WebSocket-Accept 头缺失或格式异常敏感,导致连接建立后秒断。Gateway 默认不透传或重写该头,需手动添加过滤器确保响应头合规。
- YAML 配置示例:
filters:<br> - SetResponseHeader=Sec-WebSocket-Accept,{{value}}(实际不推荐硬编码值,应让后端生成) - ✅ 更稳妥做法:去掉该 filter,改用
preserveHostHeader: true并确保后端正确处理原始Sec-WebSocket-Key - ⚠️ 如果后端是 Spring Boot WebSocket(@EnableWebSocket),它会自动计算并设置
Sec-WebSocket-Accept,此时 Gateway 只需透传所有响应头,不要干预
lb:ws:// 依赖服务注册名和健康检查
使用 lb:ws://service-id 时,Gateway 会通过 LoadBalancer 查找实例,但默认不检查 WebSocket 端口是否就绪。若服务刚启动、WebSocket handler 尚未初始化,Gateway 可能将请求转发到不可用节点,返回 503 或空响应。
- 必须确认注册中心(如 Nacos/Eureka)中该服务的元数据包含 WebSocket 端口(例如
websocket.port=8081),且健康检查端点(/actuator/health)返回 UP 时,WebSocket 实际已可连接 - 建议在服务启动类中增加简单就绪探针,例如监听
/ws/ready返回 200,再接入 Gateway 的 readiness probe - 调试时可临时切回
ws://ip:port直连,排除服务发现层干扰
最容易被忽略的是:WebSocket 连接建立后,心跳帧(ping/pong)和长连接保活完全由客户端和服务端协商控制,Gateway 不参与也不感知;一旦连接建立成功,后续所有帧都直接透传,任何中间网络设备(如 SLB、Nginx)也必须开启 WebSocket 支持,否则会在空闲几秒后静默断连。










