gRPC 的协议分析

http://www.udpwork.com/item/13900.html?utm_source=tuicool&utm_medium=referral



gRPC 和通常的基于TCP的实现不同,是直接基于HTTP2 协议的。HTTP2 使得gRPC 能够更好的适用于移动客户端和服务端通信的使用场景,并且连接多路复用也保证了RPC 的效率。

gRPC 的协议设计上很好的使用了HTTP2 现有的语义,请求和响应的数据使用HTTP Body 发送,其他的控制信息则用Header 表示。先看个例子,假设Protobuf 定义如下:

package foo.bar;

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}

service HelloService {
  rpc SayHello(HelloRequest) returns (HelloResponse);
}

在这里面我们定义了一个service HelloService。grpc 为这样一个调用发送的请求为: 

HEADERS (flags = END_HEADERS)
:method = POST
:scheme = http
:path = /foo.bar.HelloService/SayHello
:authority = api.test.com
grpc-timeout = 1S
content-type = application/grpc+proto
grpc-encoding = gzip
authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v

DATA (flags = END_STREAM)
<Delimited Message>

Http 请求的Path 部分用来表示调用哪个服务,格式是/{package}.{ServiceName}/{RpcMethodName},content-type 目前取值都是application/grpc+proto,将来gRPC 支持除Protobuf 之外的协议如Json 时,会有别的值。grpc-encoding 可以有gzip, deflate, snappy 等取值,表示采用的压缩方法。grpc-timeout 表示调用的超时时间,单位有Hour(H), Minute(M), Second(S), Millisecond(m), Microsecond(u), Nanosecond(n) 等。 

除了gRPC 定义的标准头之外,也可以自己添加新的头。如果是二进制的Header,则Header Name 以-bin 结尾,Header Value 是经过Base64 编码的二进制数据。
服务端对这个请求返回一个Response:
HEADERS (flags = END_HEADERS)
:status = 200
grpc-encoding = gzip

DATA
<Delimited Message>

HEADERS (flags = END_STREAM, END_HEADERS)
grpc-status = 0 # OK
trace-proto-bin = jher831yy13JHy3hc
grpc-status 为0 表示请求没有出现问题,成功返回。
gRPC 还定义了GOAWAY Frame, 当Server 断开一个连接的时候,需要向客户端发送这样一条消息;以及PING Frame,接受到PING Frame 后直接原样返回数据,用于连接存活检测和延迟检测。
HTTP2 的Header 并不是特别高效的格式,存储上和解析上都有一些效率问题。如果启用加密连接的话,则会有更多的效率开销。

原文链接: http://www.dongliu.net/post/622451


### gRPC协议的定义、工作原理及其使用场景 #### 定义 gRPC 是一种高性能、开源且通用的远程过程调用 (RPC) 框架,最初由 Google 开发[^1]。它利用 HTTP/2 作为传输层协议,并采用 Protocol Buffers(简称 Protobuf)作为接口描述语言 (IDL) 和数据序列化协议。这种组合使 gRPC 能够实现高效的数据传输和跨平台支持。 #### 工作原理 gRPC 的核心工作机制围绕以下几个方面展开: 1. **Protobuf IDL** gRPC 使用 Protobuf 来定义服务接口和消息结构。开发者通过 `.proto` 文件指定服务的方法签名以及输入输出参数类型。这些文件会被编译成特定语言的客户端和服务端代码[^4]。 2. **HTTP/2 支持** 借助 HTTP/2 协议的功能特性,如多路复用、头部压缩和双向流等功能,gRPC 实现了更低的网络延迟和更高的带宽利用率[^1]。 3. **四种 RPC 类型** - **Unary RPCs**: 客户端向服务器发送单一请求并接收单一响应。 - **Server Streaming RPCs**: 客户端发起请求后,服务器返回一系列连续的消息流。 - **Client Streaming RPCs**: 客户端持续向服务器发送一连串消息直到完成操作。 - **Bidirectional Streaming RPCs**: 双方均可同时读写消息形成真正的全双工通信通道[^1]。 4. **动态反射与 API 发现** 如果启用了 gRPC Reflection,则允许客户端在运行期间获取有关可用服务的信息而不必提前拥有对应的 `.proto` 文件副本[^2]。此功能对于调试工具或自动化测试框架尤为有用。 5. **浏览器兼容性扩展——gRPC Web** 鉴于原生 gRPC 不被大多数网页浏览环境所接受的情况,专门为此设计了一个变种版本叫 gRPC Web 。该方案引入了一款中间件代理来桥接前端 JavaScript 应用程序同后台真实 gRPC Server间的通讯差距[^3]。不过需要注意的是,目前 gRPC Web 并未完全覆盖所有原始特性的支持范围比如缺少对某些类型的流式交互的支持等局限性依然存在。 #### 使用场景 鉴于以上介绍的技术优势,以下是几个典型的适合运用 gRPC 技术栈的实际案例领域: - **微服务架构内部通信** 在构建现代化分布式系统过程中,往往涉及到众多细粒度划分出来的子模块之间频繁而又紧密协作的需求。此时选用具备强类型契约约束力同时也兼顾良好性能表现水平的 gRPC 就显得尤为重要了[^4]。 - **实时数据分析管道建设** 当面对海量事件驱动型应用场景时,例如物联网设备监控告警推送或者是金融交易订单匹配引擎等领域任务处理要求极高时效敏感程度下,借助 gRPC 提供的强大流控能力和可靠连接管理机制可以帮助我们更好地满足业务指标预期效果达成目的[^1]。 - **跨语言混合生态系统集成** 若项目团队成员分别擅长不同编程范式的语言表达习惯的话,那么凭借 gRPC 自身优异的多语种无缝衔接能力无疑成为了促进整体工作效率提升的一大助力因素之一。 --- ```python # Python 中创建简单的 gRPC 服务示例 import grpc from concurrent import futures import helloworld_pb2 import helloworld_pb2_grpc class Greeter(helloworld_pb2_grpc.GreeterServicer): def SayHello(self, request, context): return helloworld_pb2.HelloReply(message=f'Hello {request.name}') def serve(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port('[::]:50051') server.start() server.wait_for_termination() if __name__ == '__main__': serve() ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值