grpc 与 protobuf 的基本概念是什么?

一句话结论:protobuf 是二进制的结构化序列化协议,用 .proto 描述消息与接口并生成多语言代码(字段带编号,向后兼容靠“增字段不改号”);gRPC 是基于 HTTP/2 的 RPC 框架,支持一元、服务端流、客户端流、双向流四种调用,靠 protobuf 定义 service,适合微服务内部的高效通信。

基本概念分层

内容
IDL.proto:message 定义数据结构,service 定义 RPC 方法
序列化protobuf:字段编号加类型编码成紧凑二进制,编解码由生成代码完成
传输HTTP/2:多路复用、头部压缩、双向流、长连接
框架gRPC:stub/客户端、server、拦截器(interceptor)、deadline、metadata
工具protoc 加插件生成代码;grpcurl/grpcui 调试;health/reflection 服务

四种调用模型

  • 一元 Unary:一问一答,最常用。
  • 服务端流:客户端发一个请求,服务端持续返回多条。
  • 客户端流:客户端持续发送,服务端汇总后回一个响应。
  • 双向流:双方同时持续收发(聊天、实时同步等场景)。
syntax = "proto3";

package user;

service UserService {
	rpc GetUser (GetUserReq) returns (GetUserResp);
	rpc WatchUsers (WatchReq) returns (stream UserEvent); // 服务端流
}

message GetUserReq { int64 id = 1; }
message GetUserResp { string name = 2; }
// 生成代码后,服务端实现接口并注册
type server struct {
	pb.UnimplementedUserServiceServer
}

func (s *server) GetUser(ctx context.Context, req *pb.GetUserReq) (*pb.GetUserResp, error) {
	return &pb.GetUserResp{Name: "alice"}, nil
}

func main() {
	gs := grpc.NewServer()
	pb.RegisterUserServiceServer(gs, &server{})
	lis, _ := net.Listen("tcp", ":9000")
	_ = gs.Serve(lis)
}

与 REST/JSON 的取舍

对比gRPC + protobufREST + JSON
契约强类型、先定义后实现靠文档/OpenAPI
效率二进制小、HTTP/2 复用JSON 大、解析慢
流式原生双向流需另做 SSE/WebSocket
生态浏览器要 grpc-web 中转全端通用

gRPC 也常用 context 传递 deadline 与 metadata(鉴权 token、trace id),配合拦截器统一加日志与错误码。

常见追问 / 记忆点

  • 追问:protobuf 为什么能向后兼容?——字段靠编号不靠名字:新增用新号、删除留号占位,老客户端只读自己认识的字段。
  • 追问:gRPC 为什么比 HTTP/1.1 加 JSON 快?——二进制编码加 HTTP/2 多路复用,省掉队头阻塞与反复握手开销。
  • 记忆点:proto 定契约、protoc 生成代码、HTTP/2 传输;四种流模型;内部服务首选,对外慎选。
笔记加载中…