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不是银弹,但在微服务通信这个场景下,它确实是最趁手的兵器之一。