495 字
1 分钟
gRPC:高性能 RPC 框架详解
前言
gRPC 是 Google 开源的高性能 RPC 框架,基于 HTTP/2 传输层和 Protocol Buffers 序列化协议。本章详解 gRPC 的架构、四种 RPC 类型和实际应用。
一、gRPC 概述
1.1 核心特性
| 特性 | 说明 |
|---|---|
| 高性能 | 基于 HTTP/2,多路复用 |
| 跨语言 | 12+ 语言支持 |
| 紧凑 | Protocol Buffers 序列化 |
| 流式支持 | 服务端/客户端/双向流 |
| 生态丰富 | 负载均衡、安全、追踪 |
1.2 gRPC 架构全景
graph TB
subgraph "应用层"
A[Client Code] --> B[Stub]
C[Service Impl] --> D[Server]
end
subgraph "gRPC 层"
B --> E[Channel]
D --> F[Server Transport]
E --> G[Serializer]
F --> G
G --> H[Flow Control]
end
subgraph "传输层"
H --> I[HTTP/2]
I --> J[TLS]
end
subgraph "网络层"
J --> K[TCP]
end
style A fill:#e1f5fe
style C fill:#e1f5fe
style I fill:#fff3e0
style J fill:#fce4ec
gRPC 以 HTTP/2 为传输层,继承其二进制分帧、多路复用和流控特性。相比 WebSocket 协议 的双向消息通道,gRPC 提供更强的类型安全和代码生成能力。
1.2 gRPC vs REST
| 特性 | REST | gRPC |
|---|---|---|
| 协议 | HTTP/1.1-2 | HTTP/2 |
| 序列化 | JSON/XML | Protocol Buffers |
| 传输效率 | 低 | 高 |
| 代码生成 | OpenAPI/Swagger | 原生 Proto 生成 |
| 流式支持 | SSE/轮询 | 原生支持 |
| 浏览器支持 | 原生 | 需要 grpc-web |
二、Protocol Buffers
2.1 定义服务
syntax = "proto3";
package user;
service UserService { // unary RPC rpc GetUser(GetUserRequest) returns (User);
// 服务端流式 RPC rpc ListUsers(ListRequest) returns (stream User);
// 客户端流式 RPC rpc CreateUsers(stream CreateRequest) returns (CreateResponse);
// 双向流式 RPC rpc Chat(stream Message) returns (stream Message);}
message User { string id = 1; string name = 2; string email = 3;}2.2 数据类型映射
// Proto 类型 -> Python/Go/TypeScriptint32 -> int/numberint64 -> int/Longfloat -> float/numberdouble -> double/numberbool -> bool/booleanstring -> str/stringbytes -> bytes/Uint8Arrayrepeated -> list/arraymap -> dict/object三、HTTP/2 传输层
3.1 HTTP/2 特性
graph TB
A["gRPC"] --> B["HTTP/2"]
B --> C["多路复用"]
B --> D["头部压缩"]
B --> E["流控制"]
B --> F["二进制帧"]
subgraph "二进制帧"
G["HEADERS Frame"]
H["DATA Frame"
]
3.2 帧格式
┌─────────────────────────────────────┐│ Length (24-bit) │├─────────────────────────────────────┤│ Type (8-bit) │ Flags (8-bit) │├─────────────────────────────────────┤│ Stream ID (31-bit) │├─────────────────────────────────────┤│ Payload │└─────────────────────────────────────┘
# gRPC 帧类型# 0x00: DATA# 0x01: HEADERS# 0x04: RESET_STREAM# 0x07: GOAWAY四、RPC 类型
4.1 四种模式对比
graph LR
subgraph "Unary RPC"
A1[Client] -->|Request| B1[Server]
B1 -->|Response| A1
end
subgraph "Server Streaming"
A2[Client] -->|Request| B2[Server]
B2 -->|Stream| A2
B2 -->|Stream| A2
B2 -->|Stream| A2
end
subgraph "Client Streaming"
A3[Client] -->|Stream| B3[Server]
A3 -->|Stream| B3
A3 -->|Stream| B3
B3 -->|Response| A3
end
subgraph "Bidirectional Streaming"
A4[Client] <-->|Stream| B4[Server]
end
4.2 Unary RPC(一元 RPC)
sequenceDiagram
participant C as Client
participant S as Server
C->>S: GETUSER REQUEST
Note over S: 处理请求
S->>C: USER RESPONSE
# Python 服务端class UserServicer(user_pb2_grpc.UserServiceServicer): def GetUser(self, request, context): return user_pb2.User( id=request.id, name="张三", email="zhangsan@example.com" )4.3 服务端流式 RPC
# 服务端流def ListUsers(self, request, context): users = db.query_users(limit=request.limit) for user in users: yield user # 流式返回4.3 客户端流式 RPC
# 客户端流def CreateUsers(self, request_iterator, context): created = [] for request in request_iterator: user = db.create(request) created.append(user) return CreateResponse(users=created)4.4 双向流式 RPC
# 双向流async def Chat(self, request_iterator, context): async for message in request_iterator: reply = await process_message(message) yield reply五、元数据和拦截器
5.1 元数据
# 客户端发送元数据metadata = [("authorization", "Bearer token")]response = stub.GetUser(request, metadata=metadata)
# 服务端读取元数据def GetUser(self, request, context): token = context.invocation_metadata() auth = dict(token).get("authorization") if not auth: context.abort(grpc.StatusCode.UNAUTHENTICATED)5.2 拦截器
# 服务端拦截器class AuthInterceptor(grpc.ServerInterceptor): def intercept_service(self, continuation, handler_call_details): meta = dict(handler_call_details.invocation_metadata) if not meta.get("authorization"): return grpc.unary_unary_rpc_method_handler( lambda *args: context.abort(grpc.StatusCode.UNAUTHENTICATED) ) return continuation(handler_call_details)六、错误处理
6.1 状态码
| 状态码 | 说明 |
|---|---|
| OK | 成功 |
| INVALID_ARGUMENT | 参数错误 |
| NOT_FOUND | 资源不存在 |
| UNAUTHENTICATED | 未认证 |
| PERMISSION_DENIED | 无权限 |
| RESOURCE_EXHAUSTED | 资源耗尽 |
| INTERNAL | 内部错误 |
6.2 错误传播
# 服务端返回错误context.abort(grpc.StatusCode.NOT_FOUND, "User not found")
# 客户端捕获try: response = stub.GetUser(request)except grpc.RpcError as e: print(f"错误: {e.code()} - {e.details()}")七、gRPC-Web
7.1 架构
graph LR
A["Browser"] --> B["gRPC-Web Proxy"]
B --> C["gRPC Backend"]
subgraph "协议转换"
B --> D["HTTP/1.1"]
B --> E["HTTP/2"]
end
7.2 客户端示例
import { grpc } from "@improbable-eng/grpc-web";
// 使用 grpc-web 调用const client = grpc.invoke(UserService.GetUser, { request: request, host: "https://api.example.com", onMessage: user => { console.log(user); }, onEnd: (code, message) => {},});八、安全
8.1 TLS 传输加密
# 服务端配置server: credentials: grpc.ssl_server_credentials( server_cert, server_key )8.2 认证
# JWT 认证class JWTInterceptor(grpc.ServerInterceptor): def intercept_service(self, continuation, details): meta = dict(details.invocation_metadata()) token = meta.get("authorization", "").replace("Bearer ", "") if verify_jwt(token): return continuation(details) return lambda *args: abort(UNAUTHENTICATED)九、负载均衡
9.1 客户端负载均衡
# gRPC 负载均衡策略channel = grpc.insecure_channel( "lb:///user-service", options=[ ("grpc.load_balancing_policy", "round_robin") ])9.2 服务端负载均衡
graph TB
A["Client"] --> B["Load Balancer"]
B --> C["Server 1"]
B --> D["Server 2"]
B --> E["Server 3"]
十、总结
gRPC 以 HTTP/2 为传输层、Protocol Buffers 为序列化协议,提供了高性能、跨语言的 RPC 能力。掌握四种 RPC 类型、元数据处理和拦截器机制,是构建微服务通信层的关键技能。
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
gRPC:高性能 RPC 框架详解
https://blog.souloss.com/posts/web/grpc-protocol/ 部分信息可能已经过时
相关文章 智能推荐
1
QUIC与HTTP/3:传输层的性能革命
互联网运作 TCP的队头阻塞、握手延迟和连接迁移失败催生了QUIC——一个基于UDP的加密传输协议。0-RTT握手、流级多路复用、连接ID迁移,加上HTTP/3的QPACK头部压缩,传输层迎来了真正的性能革命。
2
HTTP/2:多路复用
web 探索 HTTP/2 如何突破 HTTP/1.1 的性能瓶颈——从 SPDY 的设计理念到二进制分帧层、多路复用、头部压缩(HPACK)、服务器推送与流优先级,用实验直观理解这些革命性改进。
3
HTTP/3:QUIC 传输
web 深入探索 HTTP/3 的革命性变化——基于 QUIC 协议的传输层如何解决 TCP 的队头阻塞问题,0-RTT 连接建立如何实现极速响应,连接迁移如何让网络切换无缝进行,以及 HTTP/3 与 HTTP/2 的关键差异。
4
HTTP协议演进:从1.0到3.0的性能革命
互联网运作 从HTTP/0.9的单行请求到HTTP/3的QUIC传输,HTTP协议三十年演进的核心驱动力是什么?HTTP/1.1的持久连接与管道化、HTTP/2的二进制帧多路复用与HPACK、HTTP/3对TCP队头阻塞的彻底终结——每一代协议都在解决上一代的性能瓶颈。
5
HTTP/1.1:持久连接
web 在 HTTP/1.0 的基础上,深入探索 HTTP/1.1 的核心改进——持久连接、分块传输编码、请求管道化、内容协商、缓存增强,以及 Host 头的重要性。通过 Python 实验服务器亲手体验这些特性带来的性能提升。






