websocket不能用于微服务间通信,因其状态化、无重试、难负载均衡;应采用“前端↔websocket服务↔消息队列↔微服务”架构,websocket服务暴露http推送接口供其他服务调用。

Spring Cloud里直接用 WebSocket 做跨微服务消息传输,本质上走不通——WebSocket 是面向前端长连接的协议,不是为服务间通信设计的。强行让 service A 作为 WebSocket 客户端去连 service B 的 /ws 端点,会立刻遇到连接管理、会话生命周期、负载不均、实例不可达等一堆问题。
为什么不能把 WebSocket 当作微服务间通信通道
微服务之间需要的是可靠、可重试、带路由和熔断能力的消息机制,而 WebSocket 连接是状态化的、有生命周期的、依赖 TCP 长连接维持的:
-
WebSocketSession对象无法序列化,存不了 Redis,分布式部署下 session 不共享 - 服务 B 有多个实例时,service A 连上的只是其中某一个,其他实例收不到消息
- 没有重连兜底、无消息确认、无顺序保证,失败即丢失
- 网关(如 Spring Cloud Gateway)默认不透传
Upgrade: websocket请求头,需额外配置且不稳定
替代方案:用 WebSocket 接前端,用消息中间件桥接后端
真正可行的架构是「前端 ↔ WebSocket 服务 ↔ 消息队列 ↔ 其他微服务」:
- 单独起一个
websocket-service,只负责处理前端连接、鉴权、广播/单推 - 该服务收到前端消息后,不直接调其他服务,而是发到
RocketMQ/RabbitMQ/Kafka - 业务服务(如
order-service、notify-service)监听对应 topic,消费后执行逻辑 - 业务服务要向前端推送结果?调用
websocket-service提供的 HTTP 接口(如POST /api/push/{userId}),由它查ConcurrentHashMap或 Redis 中的 session 并转发
这样既保留了 WebSocket 对前端的实时性,又把服务间通信交给专业中间件处理。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
若依(RuoYi-Cloud)中 WebSocketService 如何暴露内部推送能力
在 ruoyi-net 或自建 websocket-service 模块中,必须提供非 WebSocket 协议的推送入口,否则其他服务无法触发通知:
- 定义一个 REST 接口:
@PostMapping("/api/push/user/{userId}"),接收 JSON 消息体 - 接口内从
ConcurrentHashMap<string session></string>查userId对应的Session,调session.getBasicRemote().sendText(...) - 注意加锁或使用
computeIfPresent防止空指针;session 可能已关闭,需捕获IOException - 不要把
Session存 Redis —— 它不是可序列化对象;如需多实例支持,改用 Redis Pub/Sub + 每个实例监听频道并维护本地 session 映射
Gateway 网关对 WebSocket 的真实影响
Spring Cloud Gateway 默认不支持 WebSocket 透传,必须显式开启:
- 配置项
spring.cloud.gateway.routes[0].uri=lb:ws://websocket-service(注意是ws://,不是http://) - 加全局过滤器:继承
GlobalFilter,判断请求头含Upgrade: websocket时放行 - 但即便配通,Gateway 仍可能因超时、连接复用等问题中断长连接;生产环境更推荐 Nginx 做 WebSocket 反代,并设置
proxy_read_timeout 3600 - 若用 Nacos 注册中心,确保
websocket-service实例健康检查不走 HTTP 探针(WebSocket 服务没暴露 HTTP 端点),改用 TCP 或自定义心跳
真正麻烦的从来不是写几行 @ServerEndpoint,而是怎么让这个连接在滚动发布、扩容缩容、网络抖动中不掉线、不重复、不漏推——这些细节,比代码本身更决定上线成败。










