RPC 的定义这里就不再说,看文章的同学都是成熟的开发。gRPC 是 Google 开源的高性能跨语言的 RPC 方案,该框架的作者 Louis Ryan 阐述了设计这款框架的动机,有兴趣的同学可以看看: gRPC的动机和设计原则 。
另一个值得一提的问题是,众所周知 RPC 框架基本都是直接基于 TCP 协议自研数据结构和编解码方式,但是 gRPC 却完全不是这样,它使用 HTTP/2 协议来传输数据。基于这一点来说, yRPC 肯定就不是性能最佳的那一款 RPC 框架。但是在不追求顶格 QPS 的前提下,通用性和兼容性也是不可忽略的要素。
如果要探究为什么 gRPC 要选择使用 HTTP/2 作为底层协议,这个其实也很好解释。HTTP 协议作为 Web 端标准协议在 Google 内被大规模广泛使用。为了解决 1.x 的问题,Google 将自研的 SPDY 协议公开并推动基于 SPDY 的 HTTP/2 协议。所以 gRPC 从兼容性和推广 HTTP/2 两个角度来说有充足理由选择 HTTP/2,何况基于 HTTP/2 的一些新特性也会让实现方案上少写很多代码。
这里衍生出另一个基础问题:既然底层使用 HTTP/2,那为啥还要用 RPC,不直接用 Restful 的方式更直接吗。RPC 通常使用二进制编码来压缩消息的内容,Restful 更多的使用 JSON 格式,消息体中的冗余数据比较多,性能不如 RPC。
说了这么多题外话下面我们还是看一下作为业内使用率比较高的一款 RPC 框架是如何跑起来的。
开始前的准备
因为 gRPC 使用 Protocol Buffers 做为协议传输编码格式,我们先安装 Protocol Buffers 。具体安装大家可以自行搜索教程,我这里使用 mac 的 brew 来安装。
因为原生的 Protobuf 并不支持将 .proto 文件编译为 Go 源码,后面 Go 官方单独开发了一款编译插件:
go get -u github.com/golang/protobuf/protoc-gen-go
无论你是通过 go get 的方式安装还是通过别的方式,确保它在 $GOPATH/bin 中以便编译器protoc能够找到它。通过这个插件你可以将 .proto 文件编译为 Go 文件。并且在 protoc-gen-go 插件中还提供了专门的 gRPC 编译相关的支持,可以将 pb 文件中定义的 rpc service 方法渲染成 Go 对象。
这里对于安装过程简单介绍过去,因为它并不是本文介绍的要点,但是对于大家来说肯定不是那么好绕过去的