gRPC 相关介绍

发布于:2025-06-29 ⋅ 阅读:(14) ⋅ 点赞:(0)

介绍

依赖两大技术

  1. HTTP/2 作为传输协议
    • gRPC 底层用 HTTP/2,它支持:
      • 多路复用(在一条 TCP 连接中并行传输多个请求和响应)
      • 二进制传输(更紧凑、高效)
      • 流式传输(客户端流、服务端流、双向流)
    • 相比传统 HTTP/1.1 的请求-应答模式,HTTP/2 能实现长连接、减少延迟。
  2. Protocol Buffers(Protobuf)作为序列化协议
    • gRPC 用 Protobuf 来定义服务接口和数据结构,传输数据时用 Protobuf 二进制序列化,这样数据体积小,解析速度快。

可以把 gRPC 看成:

  • 一种规范和框架,用 HTTP/2 来传数据
  • Protobuf 来描述和序列化接口数据
  • 最终形成一种轻量、高效、高性能的 RPC 协议

也就是说,gRPC 没有重新造一个底层网络协议,而是在 HTTP/2 之上构建标准化、高性能的 RPC 调用规范


💡 一句话总结:gRPC = RPC 框架(协议规范) + HTTP/2(传输层) + Protobuf(序列化格式)

HTTP/2

特性 HTTP/1.1 HTTP/2
传输方式 基于纯文本 基于二进制帧
连接复用 一个连接只能串行传输一个请求(需多个 TCP 连接并发) 单一 TCP 连接中支持多路复用(并行多个请求流,不再“队头阻塞”)
头部压缩 没有 使用 HPACK 算法压缩头部减少冗余
传输效率 相对较低 高(减少 RTT 延迟、减少资源浪费)
服务器推送 没有 有(服务端可主动向客户端推资源)
性能 并行度差,需拼接多个域名或连接 并行度高,减少 TCP 握手延迟,网络利用率更好

🔥 HTTP/2 性能为啥快?

  • 多个请求/响应在单一连接中同时传输 → 避免排队
  • 用二进制减少解析开销
  • HPACK 压缩请求头减少重复数据
  • 有流优先级控制,能保证重要资源先传完

💡 其实 Nginx 并不是直接把 HTTP/1.1 “升级”为 HTTP/2,而是

对外客户端提供 HTTP/2 支持

也就是:

  • 浏览器 → Nginx:用 HTTP/2
  • Nginx → 你的服务:可能是 HTTP/1.1,也可能是 HTTP/2

这种中间转换称为反向代理,它负责帮你让前端用户能用 HTTP/2,而你的后台服务暂时不用改。

FastAPI 底层用的是 UvicornHypercorn 这样的 ASGI 服务器。这些服务器默认只实现 HTTP/1.1,也就是浏览器跟你的服务之间是 HTTP/1.1。

  • 🔍 Uvicorn 默认:只支持 HTTP/1.1,不直接支持 HTTP/2
  • 🔍 Hypercorn:可以通过 TLS 配置支持 HTTP/2

✅ Uvicorn 自己目前只支持 HTTP/1.1,而要用 HTTP/2 就要用前端反代或者换成支持 HTTP/2 的服务器(如 Hypercorn)。

Protobuf

Protobuf(Protocol Buffers)Google 开发的一种二进制序列化协议,用来把结构化数据(像对象、消息、DTO)序列化成紧凑、高效的二进制流。

与 JSON 相比:

  • JSON:人可读(纯文本),体积大,序列化/反序列化较慢。
  • Protobuf:不可读二进制,需要 .proto 定义文件生成对应类,体积非常小,序列化/反序列化快
对比点 JSON Protobuf
格式 文本(UTF-8) 二进制(紧凑)
消息定义 无需预先定义 需先定义 .proto
序列化体积 小(字段编号、无冗余)
序列化速度 快(直接写入二进制缓冲区)
易读性 人可读 不可读(需工具解码)
是否可压缩 仍可 gzip 也能 gzip(再小一层)

换句话说:

  • Protobuf 相当于把对象紧凑地按二进制序列化(去掉字段名,换成字段编号、可变长整型等),属于数据结构优化
  • gzip 相当于对一串二进制做通用压缩算法(熵编码/LZ77等),属于算法级压缩
{
  "a": "b",
  "count": 123
}

定义消息规范,比如 my_data.proto:

syntax = "proto3";

message MyData {
  string a = 1;
  int32 count = 2;
}
JSON Protobuf
{“a”: “b”, “count”: 123} b’\n\x01b\x10{'(二进制)
直接可读 需用 .proto 定义结构
序列化速度较慢 序列化速度快
体积大 体积非常小

本地命令行测试公开gPRC

brew install grpcurl
grpcurl -plaintext grpcb.in:9000 list
  • grpcurl 工具
  • plaintext 表示用明文(非 TLS 加密),因为测试站点 grpcb.in:9000 没有启用 TLS
  • list 会列出该 gRPC 服务提供的所有服务名称。

返回结果:


addsvc.Add
grpc.gateway.examples.examplepb.ABitOfEverythingService
grpc.reflection.v1alpha.ServerReflection
grpcbin.GRPCBin
hello.HelloService

你先用 list grpcbin.GRPCBin 查看它的方法:

➜  ~ grpcurl -plaintext grpcb.in:9000 list grpcbin.GRPCBin
grpcbin.GRPCBin.DummyBidirectionalStreamStream
grpcbin.GRPCBin.DummyClientStream
grpcbin.GRPCBin.DummyServerStream
grpcbin.GRPCBin.DummyUnary
grpcbin.GRPCBin.Empty
grpcbin.GRPCBin.HeadersUnary
grpcbin.GRPCBin.Index
grpcbin.GRPCBin.NoResponseUnary
grpcbin.GRPCBin.RandomError
grpcbin.GRPCBin.SpecificError
➜  ~ grpcurl -plaintext grpcb.in:9000 grpcbin.GRPCBin/Empty
{}
➜  ~ grpcurl -plaintext -d '{}' grpcb.in:9000 grpcbin.GRPCBin/DummyUnary
{}

gRPC本质

本质上 gRPC 就是:

网络通信服务

用 HTTP/2 做底层传输,跨网络/不同语言之间调用

高性能序列化

用 Protobuf 把数据压缩成二进制流传过去(对比 JSON 快很多,也体积更小)

远程过程调用(RPC)

客户端像本地调用函数一样调用远程服务,gRPC 负责帮你打包、发送、等待返回

gRPC 就是让Go 调用 Python 函数 这么方便又快的工具!

比如:

  • 你有个 Python 模型服务,Go 微服务要用
  • 用 gRPC 定义接口
  • 两边各自用对应语言生成代码
  • 直接 stub.MyService.Method() 像本地函数一样调用,但是底层走网络传 Protobuf 消息

🧠 为什么大家喜欢 gRPC:

  1. 🏎 — 二进制流,HTTP/2 多路复用。
  2. 🧮 类型安全 — .proto 定义好了,生成各语言客户端。
  3. ⚖️ 通用 — Go/Python/Java/… 全部支持。

🎯 也就是:一份 .proto,多语言生成各自代码,这就是 gRPC 的核心

让不同语言像调用本地函数一样调用远程服务!


网站公告

今日签到

点亮在社区的每一天
去签到