高 进阶
gRPC核心概念与工作原理#
一句话答案#
gRPC 是 Google 开源的高性能 RPC 框架,基于 HTTP/2 传输 + Protobuf 序列化,支持四种通信模式(Unary/Server-stream/Client-stream/Bidirectional),天然支持多语言、流式通信和双向流。
核心要点
架构分层#
Client Stub (生成代码)
↓ Protobuf 序列化
Channel (HTTP/2 连接管理)
↓ HTTP/2 帧
Transport (TCP / TLS)
↓
Server: Interceptor → Service Implementationplaintext核心组件#
| 组件 | 作用 |
|---|---|
.proto 文件 | 接口定义语言(IDL),定义 service 和 message |
protoc 编译器 | 从 .proto 生成客户端 Stub 和服务端骨架代码 |
| Channel | 客户端到服务端的虚拟连接,内部管理 HTTP/2 连接池 |
| Stub | 客户端调用代理,封装序列化 + 网络通信 |
| Server | 监听端口,注册 Service 实现,处理请求 |
四种通信模式#
service OrderService {
// 1. Unary: 一请求一响应(最常用,类似 REST)
rpc GetOrder(OrderRequest) returns (OrderResponse);
// 2. Server Streaming: 一请求多响应(适合推送、分页拉取)
rpc ListOrders(ListRequest) returns (stream OrderResponse);
// 3. Client Streaming: 多请求一响应(适合上传、批量写入)
rpc UploadOrders(stream OrderRequest) returns (UploadResponse);
// 4. Bidirectional Streaming: 双向流(适合聊天、实时同步)
rpc Chat(stream ChatMessage) returns (stream ChatMessage);
}protobuf为什么快?#
- HTTP/2 多路复用:一个 TCP 连接并行多个请求,无队头阻塞
- Protobuf 二进制序列化:体积比 JSON 小 3-5 倍,解析速度快 5-10 倍
- Header 压缩(HPACK):减少重复 header 传输
- 连接复用:Channel 内部维护长连接池,避免频繁握手
- 流式传输:大数据集不需要一次性装入内存
gRPC 服务注册与发现#
gRPC 本身不提供服务发现,需要集成:
- Nacos / Consul / etcd 作为注册中心
- 客户端负载均衡:gRPC 内置 pick_first / round_robin
- 也可用 Envoy / Istio 做 sidecar 代理plaintextJava 中使用 gRPC#
// 服务端
Server server = ServerBuilder.forPort(9090)
.addService(new OrderServiceImpl())
.addService(ServerInterceptors.intercept(service, authInterceptor))
.build()
.start();
// 客户端
ManagedChannel channel = ManagedChannelBuilder
.forTarget("dns:///order-service:9090")
.usePlaintext()
.build();
OrderServiceGrpc.OrderServiceBlockingStub stub =
OrderServiceGrpc.newBlockingStub(channel);java面试回答(2分钟版)
gRPC 是 Google 开源的高性能 RPC 框架,底层用 HTTP/2 做传输、Protobuf 做序列化。相比传统 REST+JSON,优势在于:HTTP/2 多路复用避免队头阻塞,Protobuf 二进制编码体积小 3-5 倍、解析快一个数量级,加上 HPACK 头压缩和连接复用,性能远高于 HTTP/1.1+JSON。gRPC 支持四种通信模式:Unary 一问一答、Server Streaming 服务端推流、Client Streaming 客户端上传流、Bidirectional 双向流。开发流程是先写 .proto IDL 定义 service 和 message,然后用 protoc 生成客户端 Stub 和服务端骨架代码,天然跨语言。gRPC 本身不带服务发现,实际使用中结合 Nacos 或 etcd 做注册中心,负载均衡可以用内置的 round_robin 或者 Envoy sidecar。在微服务内部通信场景下 gRPC 是首选,对外暴露仍用 REST(浏览器兼容性)。
追问与易错
追问方向:
- “gRPC 和 Dubbo 什么区别?”→ gRPC 跨语言更强、基于 HTTP/2;Dubbo 生态更丰富(注册中心/治理一体化)、支持多协议
- “gRPC 怎么做服务发现?”→ 集成 Nacos/etcd/Consul,或用 Kubernetes Service + DNS
- “HTTP/2 多路复用怎么实现的?”→ 二进制分帧,每个请求是独立的 stream ID,不互相阻塞
- “gRPC 超时和重试怎么配?”→ 客户端 deadline propagation + retry policy(JSON 配置 maxAttempts/retryableStatusCodes)
易错点:
- ❌ “gRPC 只能用 Protobuf”——也支持 JSON 序列化,但性能优势会丧失
- ❌ “gRPC 不能在浏览器用”——gRPC-Web 可以,但需要 Envoy 代理转译
- ❌ “HTTP/2 就不需要连接池”——单连接有带宽上限,高并发仍需多连接