面试知识库
进阶

gRPC流式通信模式#

一句话答案#

gRPC 基于 HTTP/2 的 stream 机制提供四种通信模式:Unary(一问一答)、Server Streaming(服务端推流)、Client Streaming(客户端上传流)、Bidirectional Streaming(双向流),解决了 REST 无法优雅处理的实时推送、大数据分批传输和双向通信场景。

核心要点

四种模式对比#

模式请求响应典型场景
Unary11CRUD 操作、普通查询
Server Streaming1N日志推送、实时行情、分页拉取
Client StreamingN1文件上传、批量数据写入、IoT 采集
BidirectionalNN聊天、协同编辑、实时游戏

Server Streaming 示例#

Bidirectional Streaming 示例#

// Proto 定义
rpc Chat(stream ChatMessage) returns (stream ChatMessage);

// 服务端
@Override
public StreamObserver<ChatMessage> chat(StreamObserver<ChatMessage> responseObserver) {
    return new StreamObserver<ChatMessage>() {
        @Override public void onNext(ChatMessage msg) {
            // 收到客户端消息,处理后推回
            responseObserver.onNext(process(msg));
        }
        @Override public void onCompleted() { responseObserver.onCompleted(); }
        @Override public void onError(Throwable t) { /* handle */ }
    };
}
java

流控(Flow Control)#

HTTP/2 内置流控机制:
1. 连接级窗口:控制整个连接的总数据量
2. Stream 级窗口:控制单个 stream 的数据量
3. 接收方通过 WINDOW_UPDATE 帧通知发送方可以继续发

gRPC 层面:
- 客户端可以调用 request(n) 指定拉取数量(Reactive 风格)
- 服务端检测 isReady() 避免无限制推送导致 OOM
plaintext

Streaming vs WebSocket vs SSE#

维度gRPC StreamingWebSocketSSE
协议HTTP/2升级为 WS 协议HTTP/1.1
方向四种模式全双工服务端→客户端
序列化Protobuf(强类型)自定义文本
浏览器支持需 gRPC-Web 代理原生原生
适用服务间通信前端实时前端通知
面试回答(2分钟版)

gRPC 利用 HTTP/2 的 stream 特性支持四种通信模式。Unary 就是普通的一问一答,覆盖大部分 CRUD 场景。Server Streaming 适合服务端向客户端推送大量数据,比如日志流、实时行情,客户端发一个请求,服务端通过 onNext 逐条推送、onCompleted 结束。Client Streaming 适合批量上传场景,客户端连续发多条数据,服务端最后汇总返回一个结果。Bidirectional Streaming 是双向流,双方都可以随时发送,适合聊天和协同编辑。底层靠 HTTP/2 的多路复用和流控窗口保证不会 OOM:接收方通过 WINDOW_UPDATE 帧通知发送方能继续发多少。和 WebSocket 对比,gRPC Streaming 的优势是强类型(Protobuf IDL 约束)、原生流控、适合服务间通信;WebSocket 优势是浏览器原生支持。

追问与易错

追问方向:

  • “Streaming 怎么做流控?”→ HTTP/2 窗口机制 + gRPC 的 isReady()/request(n)
  • “Bidirectional 和 WebSocket 什么区别?”→ 协议不同、gRPC 强类型、需代理才能给浏览器用
  • “流中间出错怎么办?”→ onError 回调 + Status Code + 客户端可以 retry
  • “能做到消息有序吗?”→ 单个 stream 内有序,多个 stream 无序

易错点:

  • ❌ “Streaming 会占满一个 TCP 连接”——HTTP/2 多路复用,一个连接可以并行多个 stream
  • ❌ “Server Streaming 就是长轮询”——本质是服务端主动推送,不是客户端反复请求
  • ❌ “双向流需要两个连接”——一个 HTTP/2 连接内双向 stream