微服务中WebSocket需网关显式配置lb:ws://协议、Path精确匹配、改用WebSocketHandler编程注册,并通过Redis外置会话状态及前端重连机制保障高可用。

微服务架构下直接用 @ServerEndpoint 暴露 WebSocket 端点,前端连不上——不是代码写错了,是网关没配对协议、没放行路径、没处理负载均衡实例漂移。
Gateway 路由必须显式声明 lb:ws:// 协议
Spring Cloud Gateway 默认只代理 HTTP/HTTPS 流量,ws 和 wss 必须单独配置路由,且 uri 值不能是 lb://service-name(这是 HTTP 默认行为),必须写成 lb:ws://service-name。
常见错误现象:WebSocket connection to 'ws://xxx/ws/push' failed: Error during WebSocket handshake: Unexpected response code: 404 或直接 503。
-
lb:ws://中的ws是协议标识,缺了它 Gateway 就当普通 HTTP 转发,后端收不到 Upgrade 请求 - 路由
predicates的Path必须覆盖完整前缀,比如前端连ws://gateway-host/ws/push/123,那Path=/ws/push/**才匹配,/push/**不行 - 多个 WebSocket 服务建议用不同路由 ID 和路径前缀隔离,避免
StripPrefix错位导致后端路径解析失败
业务服务不能依赖 ServerEndpointExporter 自动注册
若依或 Spring Boot 2.x+ 微服务中,若使用 @ServerEndpoint 注解方式,在 Undertow 或 WebFlux 容器下会失效——因为 ServerEndpointExporter 仅对 Tomcat 生效,且无法感知注册中心的服务实例变更。
正确做法是改用 Spring WebSocket + WebSocketHandler 编程式注册,配合 @Configuration + WebSocketConfigurer。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 删掉
@ServerEndpoint类和ServerEndpointExporterBean - 实现
WebSocketHandler处理afterConnectionEstablished、handleTextMessage等生命周期 - 在
registerWebSocketHandlers中调用registry.addHandler(...).setAllowedOrigins("*"),否则跨域直接拦截 - 若需路径带参数(如
/ws/push/{userId}),得自己从WebSocketSession.getUri().getPath()解析,注解方式在此场景下不可靠
网关与业务服务间长连接状态不一致的坑
Gateway 转发 WebSocket 后,业务服务看到的 Session.getId() 是 Gateway 生成的,不是客户端原始 socket ID;更关键的是:Gateway 不维护后端服务的连接映射表,一旦某台 instance 重启或下线,已建立的连接就断开,且无自动重连机制。
这意味着你不能在业务服务里用 ConcurrentHashMap 存所有 session 并广播——它只反映本机当前连接,不是全局视图。
- 需要引入外部存储(如 Redis)存用户 ID → Session ID 映射,并用发布订阅同步连接变更事件
- 前端必须实现断线重连逻辑,且重连 URL 应带鉴权参数(如 token),避免每次重连都走登录流程
- Gateway 层建议加
spring.cloud.gateway.httpclient.response-timeout配置,防止空闲连接被中间设备(Nginx、防火墙)静默关闭 - 若用 Nginx 做最外层反代,还需额外配置
proxy_http_version 1.1、proxy_set_header Upgrade $http_upgrade、proxy_set_header Connection "upgrade"
真正难的不是写通第一个 ws:// 连接,而是让成千上万的连接在多实例、滚动发布、网络抖动下保持可用——这时候路由协议、连接生命周期管理、状态外置,三者缺一不可。










