WebSocket与gRPC:全双工通信与高效RPC

WebSocket:全双工实时通信 HTTP的局限 HTTP请求-响应模式: 客户端 → 服务器: 请求 客户端 ← 服务器: 响应 问题: - 服务器无法主动推送 - 实时性差(需要轮询) 轮询(Polling): 客户端每隔1秒请求一次: GET /api/messages(1秒后) GET /api/messages(2秒后) GET /api/messages(3秒后) ... 问题:大量无效请求,浪费资源 长轮询(Long Polling): 客户端请求,服务器挂起直到有新消息: GET /api/messages ... 服务器等待30秒 ... ← 返回新消息 问题:仍然是请求-响应模式,连接频繁断开重连 WebSocket协议 核心特点: 全双工通信(双向同时传输) 基于TCP 低开销(头部仅2字节) 持久连接 协议升级: # 客户端发起升级请求 GET /chat HTTP/1.1 Host: example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 # 服务器同意升级 HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= # 升级完成,使用WebSocket通信 Spring Boot WebSocket 服务端 // WebSocket配置 @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(chatHandler(), "/chat") .setAllowedOrigins("*"); // CORS } @Bean public ChatHandler chatHandler() { return new ChatHandler(); } } // WebSocket处理器 @Component public class ChatHandler extends TextWebSocketHandler { private static final Set<WebSocketSession> sessions = new CopyOnWriteArraySet<>(); @Override public void afterConnectionEstablished(WebSocketSession session) { sessions.add(session); System.out.println("新连接:" + session.getId()); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String payload = message.getPayload(); System.out.println("收到消息:" + payload); // 广播给所有客户端 for (WebSocketSession s : sessions) { if (s.isOpen()) { s.sendMessage(new TextMessage("服务器转发:" + payload)); } } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { sessions.remove(session); System.out.println("连接关闭:" + session.getId()); } } 客户端(JavaScript) // 建立WebSocket连接 const ws = new WebSocket('ws://localhost:8080/chat'); // 连接打开 ws.onopen = () => { console.log('WebSocket连接已建立'); ws.send('你好,服务器'); }; // 接收消息 ws.onmessage = (event) => { console.log('收到消息:', event.data); }; // 连接关闭 ws.onclose = () => { console.log('WebSocket连接已关闭'); }; // 连接错误 ws.onerror = (error) => { console.error('WebSocket错误:', error); }; STOMP:WebSocket消息协议 问题 原始WebSocket只传输文本/二进制: ...

2025-11-20 · maneng

服务间通信:同步调用、异步消息与事件驱动

引子:一次服务雪崩引发的思考 2020年双11凌晨2点,某电商平台订单服务突然不可用,导致用户无法下单。 故障链路: 用户下单 → 订单服务 → 库存服务(超时20秒) → 订单服务线程池耗尽 → 整个系统不可用 问题根源: 订单服务同步调用库存服务(HTTP请求) 库存服务压力大,响应慢(20秒超时) 订单服务线程池耗尽(200个线程全部阻塞) 新的订单请求无法处理,系统崩溃 架构师王明的反思: “同步调用的问题是什么?” “为什么不用异步消息?” “什么场景用同步,什么场景用异步?” 这个案例揭示了微服务通信的核心问题:如何选择合适的通信模式,平衡性能、可靠性、复杂度? 一、通信模式的本质:耦合度与可靠性的权衡 1.1 通信模式的两个维度 维度1:同步 vs 异步 维度 同步通信 异步通信 调用方式 请求→等待→响应 请求→立即返回→回调 阻塞性 调用方阻塞等待 调用方不阻塞 耦合度 强耦合(时间耦合) 弱耦合(时间解耦) 响应时间 快(毫秒级) 慢(秒级或分钟级) 可用性 低(被调用方挂了,调用方也挂) 高(被调用方挂了,消息不丢失) 复杂度 低(简单直接) 高(需要消息队列) 维度2:点对点 vs 发布订阅 维度 点对点(P2P) 发布订阅(Pub/Sub) 调用关系 一对一 一对多 耦合度 强耦合(空间耦合) 弱耦合(空间解耦) 扩展性 差(新增消费者要修改代码) 好(新增消费者不影响发布者) 典型场景 RPC调用 领域事件 1.2 耦合度的四个维度 1. 时间耦合(Temporal Coupling) ...

2025-11-03 · maneng

如约数科科技工作室

浙ICP备2025203501号

👀 本站总访问量 ...| 👤 访客数 ...| 📅 今日访问 ...