高 进阶
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 | 客户端到服务端的虚拟连接,内部做名字解析 + 负载均衡,按后端地址维护 Subchannel(每个地址通常一条 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 连接并行多个请求,消除 HTTP/1.1 应用层的队头阻塞(TCP 层丢包时的队头阻塞仍在,HTTP/3 才解决)
- 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(new OrderServiceImpl(), 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 多路复用避免 HTTP/1.1 的应用层队头阻塞,Protobuf 二进制编码体积更小、解析更快(常见数据下小几倍),加上 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 等代理转译(部分服务端框架如 ASP.NET Core 可内置 gRPC-Web 支持)
- ❌ “HTTP/2 就不需要连接池”——单连接受服务端 MAX_CONCURRENT_STREAMS(常见默认 100)和单连接吞吐限制,高并发仍可能需要多连接