第1章:gRPC简介与基础概念——它到底是什么?

1.1 一个真实场景引出的问题

我第一次接触gRPC,其实挺晚的。那时候公司要做微服务改造,服务间调用全用REST接口。你知道的,REST接口传JSON,看着挺友好,但压测一上,问题就来了——序列化慢、带宽占用高、接口文档还得单独维护。

后来我试着引入了gRPC。说实话,第一次部署的时候心里也没底。但用下来之后,我只想说一句话:早该换了。

gRPC,全称是gRPC Remote Procedure Calls。它由谷歌在2015年开源,核心目标就一个:让服务间通信像本地函数调用一样简单、高效、安全。

一句话概括:gRPC是一个高性能、跨语言的远程过程调用(RPC)框架,底层基于HTTP/2,数据序列化使用Protocol Buffers。

说白了,你写好一个proto文件定义接口,然后gRPC自动生成客户端和服务端代码。你只需要关心业务逻辑,不用管底层的网络通信细节。

1.2 gRPC能帮你解决什么问题?

我简单列几个痛点,你看看是不是也遇到过:

  • 接口文档不同步——service层改了参数,前端调了半天才发现
  • 性能不够——JSON解析占CPU,消息体大导致网络带宽吃紧
  • 多语言支持难——Java服务、Python服务、Go服务,每个都得重新实现一遍通信逻辑
  • 缺乏流式支持——想做个实时推送,得自己搞WebSocket或者轮询

gRPC能一次性把这些坑填平。我个人习惯,只要涉及微服务间的内部通信,优先考虑gRPC。对外部接口,还是用REST更合适——毕竟不是所有客户端都装了protobuf解码器嘛。

1.3 gRPC的四大核心特性

特性 说明 我的一点体会
基于HTTP/2 复用连接、头部压缩、支持服务器主动推送 压测时能看到连接数比REST少一个数量级
使用Protocol Buffers 高效的二进制序列化格式,体积小、速度快 同样的数据,protobuf比JSON小3~10倍
支持多种调用模式 Unary、服务端流、客户端流、双向流 做实时推送场景时,双向流简直救了我
跨语言、跨平台 官方支持C++、Java、Go、Python、Ruby等十多种语言 我们Java后端和Python算法组,用同一个proto文件,谁都不用迁就谁

1.4 那HTTP/2到底好在哪里?

你会问,REST也能用HTTP/2啊,凭啥gRPC就特别快?

嗯,关键在于gRPC强制使用HTTP/2,并且充分利用了它的特性。我来拆解一下:

  • 二进制分帧层——HTTP/1.x是文本协议,HTTP/2是二进制协议,解析效率更高
  • 多路复用——一个TCP连接可以并发处理多个请求,不会出现HTTP/1.x的队头阻塞
  • 头部压缩——使用HPACK算法压缩请求头,减少冗余数据
  • 服务器推送——服务端可以主动向客户端推送内容,减少请求次数

我记得第一次压测gRPC接口时,看到CPU占用率比REST接口低了快40%,带宽也省了一半。那一刻我真的信了——技术选型对了,运维成本能省一大截。

小提示:gRPC虽然底层用HTTP/2,但你不必直接操作HTTP/2的API。框架已经帮你封装好了。你只需要关心proto文件怎么写,业务逻辑怎么实现。

1.5 再聊聊Protocol Buffers

Protocol Buffers,简称protobuf。它是一种与语言无关、平台无关的序列化格式。你用.proto文件定义数据结构,然后用protoc编译器生成各语言的代码。

一个典型的proto文件长这样:

syntax = "proto3";

package user;

service UserService {
  rpc GetUser(GetUserRequest) returns (GetUserResponse);
}

message GetUserRequest {
  int32 user_id = 1;
}

message GetUserResponse {
  string name = 1;
  int32 age = 2;
  string email = 3;
}

你看,定义清晰,自动生成代码,不用再手写JSON序列化和反序列化。而且proto文件本身就是接口文档,文档即代码,代码即文档。

我曾经遇到过一个坑:团队里有人把protobuf和JSON混用,结果序列化格式不一致,导致解析失败。我的建议是——一旦确认用protobuf,就从头到尾统一,别搞两套。

1.6 gRPC vs REST——该选谁?

你可能会纠结:什么时候用gRPC,什么时候用REST?

我直接给你一个判断标准,用表格对比比较清楚:

对比维度 gRPC REST
传输格式 二进制(protobuf) 文本(JSON/XML)
性能 高 一般
浏览器支持 需要gRPC-Web 原生支持
调试友好度 需要工具解析 直接curl就能看
流式支持 原生支持 需额外实现
适合场景 微服务内部、低延迟、高吞吐 对外API、浏览器客户端

1.7 咱们这门课要干什么?

好了,基础介绍到这里。你已经有概念了:gRPC很强大,性能和安全性都很棒。

但有个问题——gRPC默认没有对通信内容做透明加密。虽然它支持TLS,但那属于传输层加密。如果你想在应用层做更细粒度的加密改造,或者需要兼容已有的加密体系,那就得自己动手。

这门课的目标,就是带你一步步把gRPC接口改造为透明加密。从协议设计、密钥管理、安全认证,到实际代码实现和性能调优。你会学到怎么在不入侵业务逻辑的前提下,给每个RPC调用加上一把锁。

嗯,思路清楚了就往下走吧。先看我画的一张图,把gRPC的体系结构给你理一遍。

gRPC核心知识体系结构图 gRPC核心知识体系 gRPC HTTP/2 传输层 Protocol Buffers 多路复用 头部压缩 服务器推送 二进制编码 强类型 跨语言生成 四种调用模式 Unary(一元) 服务端流 客户端流 双向流

从这张图你能看出来,gRPC的核心是HTTP/2 + Protocol Buffers,它们共同支撑起高性能通信。而四种调用模式,则让你能灵活应对不同的业务需求。

特别注意:如果你用的是Java,io.grpc包和protobuf-java的版本一定要匹配。我曾经吃过版本不兼容的亏,编译通过了,运行时一直报Method not found。排查了半天,最后发现是protobuf版本差了0.1。

好了,第一章就到这里。你对gRPC已经有了一个整体认知。下一件事,就是准备好环境,咱们开始实战。但先别急——我会带你把基础概念夯实,再动手写代码。

过程中有任何困惑,记得回到这一章来重新梳理图上这些关系。清楚了体系,后面才能走得稳。