1. Go语言与gRPC初探:gRPC是什么、为什么选择gRPC、gRPC与RESTful对比、环境搭建
大家好,欢迎来到这门课的第一章。
说实话,每次我接手一个新项目,第一件事就是琢磨服务之间怎么通信。微服务拆得越细,通信的痛点就越明显。几年前我在一个电商平台做架构升级,服务从十几个膨胀到上百个,RESTful接口调来调去,性能问题、类型安全问题接踵而至。那时候我就想,一定有个更好的方案。
后来我遇到了gRPC。嗯,今天我们就来好好聊聊它。
gRPC是什么?
gRPC,全称是gRPC Remote Procedure Calls。说白了,就是一个高性能、跨语言的远程过程调用框架。它由Google开源,底层基于HTTP/2协议,数据序列化用的是Protocol Buffers(简称protobuf)。
你可以这么理解:以前你调用一个本地函数,比如 Add(1, 2),直接返回结果。现在这个函数跑在另一台机器上,你照样可以像调用本地函数一样调用它——这就是RPC。gRPC就是帮你把这个过程做得又快又稳的那个框架。
核心特点:
- 基于HTTP/2,支持多路复用、双向流、头部压缩
- 默认使用Protocol Buffers序列化,数据体积小、解析快
- 支持多种语言(Go、Java、Python、C++等)
- 自动生成客户端和服务端代码
为什么选择gRPC?
你可能会问:我直接用RESTful JSON不也挺好?没错,小项目、对外API用RESTful完全没问题。但一旦进入微服务内部通信,gRPC的优势就出来了。
第一,性能碾压。 我在项目中做过压测,同样一个查询接口,gRPC的吞吐量是RESTful JSON的3-5倍。原因很简单:protobuf是二进制格式,比JSON小得多;HTTP/2的多路复用又省去了连接开销。
第二,强类型契约。 你想想看,RESTful接口的文档和代码经常对不上。gRPC用.proto文件定义接口,客户端和服务端都从这个文件生成代码。接口变了?编译直接报错。我曾经因为一个字段名拼写错误,线上排查了整整两个小时——用gRPC就不会有这种问题。
第三,流式通信。 gRPC支持四种通信模式:简单RPC、服务端流、客户端流、双向流。比如实时推送、大文件上传,用双向流简直不要太爽。
我的建议: 内部微服务通信首选gRPC,对外暴露API可以继续用RESTful。两者不冲突,甚至可以共存。
gRPC与RESTful对比
我们来做个直观的对比,这样你心里更有数。
| 对比维度 | gRPC | RESTful |
|---|---|---|
| 底层协议 | HTTP/2 | HTTP/1.1(通常) |
| 数据格式 | Protocol Buffers(二进制) | JSON / XML(文本) |
| 性能 | 高(体积小、速度快) | 中等 |
| 接口定义 | 强类型(.proto文件) | 弱类型(文档约定) |
| 流式支持 | 原生支持(双向流) | 需额外实现(SSE、WebSocket) |
| 浏览器支持 | 有限(需gRPC-Web) | 原生支持 |
| 学习曲线 | 中等(需学protobuf) | 低 |
看到没?gRPC在性能和契约化方面优势明显,但浏览器支持是个短板。所以实际项目中,我经常是gRPC做内部通信,RESTful做对外网关。
环境搭建
好了,理论说完了,咱们动手吧。环境搭建这块,我踩过不少坑,你跟着我的步骤来,能省不少时间。
1. 安装Go
Go的安装很简单,去官网下载对应版本就行。我个人习惯用1.21以上版本,对泛型和工具链支持更好。
# 验证安装
go version
# 输出类似:go version go1.21.0 darwin/amd64
注意: 确保$GOPATH/bin在你的PATH环境变量中。我曾经因为忘了这步,折腾了半天才发现工具装上了但找不到。
2. 安装protoc
protoc是Protocol Buffers的编译器。它负责把.proto文件编译成各种语言的代码。
# macOS
brew install protobuf
# Ubuntu
apt-get install -y protobuf-compiler
# 验证
protoc --version
# 输出类似:libprotoc 25.1
3. 安装protoc-gen-go
这个插件负责生成Go语言的gRPC代码。注意,现在官方推荐用protoc-gen-go-grpc来生成gRPC服务代码,而不是老版本的protoc-gen-go。
# 安装protoc-gen-go
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
# 安装protoc-gen-go-grpc
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
# 验证
which protoc-gen-go
which protoc-gen-go-grpc
避坑指南: 我曾经用老版本的protoc-gen-go生成代码,结果死活跑不通。后来才发现新版本已经拆分了。记住:protoc-gen-go只生成消息类型代码,protoc-gen-go-grpc才生成服务端和客户端代码。
4. 验证环境
写一个最简单的.proto文件试试手。
// hello.proto
syntax = "proto3";
package hello;
option go_package = "hello/";
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
# 编译
protoc --go_out=. --go-grpc_out=. hello.proto
# 检查生成的文件
ls
# 应该看到:hello.pb.go 和 hello_grpc.pb.go
看到这两个文件生成成功,说明你的环境已经搭好了。嗯,就是这么简单。
小结
这一章我们聊了gRPC是什么、为什么选它、和RESTful的对比,最后把环境搭好了。说实话,环境搭建是很多人放弃的第一步,但跟着我的步骤走,应该不会出问题。
下一章,我们会真正写一个gRPC服务端和客户端,跑通第一个Hello World。到时候你会发现,gRPC用起来其实比RESTful还顺手。
记住:工具是死的,思路是活的。gRPC不是银弹,但在微服务通信这个场景下,它确实是最趁手的兵器之一。