介绍
我猜测大部分长期使用 Java
的开发者应该较少会接触 gRPC
,毕竟在 Java
圈子里大部分使用的还是 Dubbo/SpringClound
这两类服务框架。
我也是近段时间有机会从零开始重构业务才接触到 gRPC
的,当时选择 gRPC
时也有几个原因:
网络异常,图片无法展示
|
- 基于云原生的思路开发部署项目,而在云原生中
gRPC
几乎已经是标准的通讯协议了。
- 开发语言选择了 Go,在 Go 圈子中
gRPC
显然是更好的选择。
- 公司内部有部分业务使用的是
Python
开发,在多语言兼容性上gRPC
支持的非常好。
经过线上一年多的平稳运行,可以看出 gRPC
还是非常稳定高效的;rpc 框架中最核心的几个要点:
- 序列化
- 通信协议
- IDL(接口描述语言)
这些在 gRPC
中分别对应的是:
- 基于
Protocol Buffer
序列化协议,性能高效。
- 基于
HTTP/2
标准协议开发,自带stream
、多路复用等特性;同时由于是标准协议,第三方工具的兼容性会更好(比如负载均衡、监控等)
- 编写一份
.proto
接口文件,便可生成常用语言代码。
HTTP/2
学习 gRPC
之前首先得知道它是通过什么协议通信的,我们日常不管是开发还是应用基本上接触到最多的还是 HTTP/1.1
协议。
网络异常,图片无法展示
|
由于 HTTP/1.1
是一个文本协议,对人类非常友好,相反的对机器性能就比较低。
需要反复对文本进行解析,效率自然就低了;要对机器更友好就得采用二进制,HTTP/2
自然做到了。
除此之外还有其他优点:
- 多路复用:可以并行的收发消息,互不影响
HPACK
节省header
空间,避免HTTP1.1
对相同的header
反复发送。
Protocol
gRPC
采用的是 Protocol
序列化,发布时间比 gRPC
早一些,所以也不仅只用于 gRPC
,任何需要序列化 IO 操作的场景都可以使用它。
它会更加的省空间、高性能;之前在开发 github.com/crossoverJi… 时就使用它来做数据交互。
package order.v1; service OrderService{ rpc Create(OrderApiCreate) returns (Order) {} rpc Close(CloseApiCreate) returns (Order) {} // 服务端推送 rpc ServerStream(OrderApiCreate) returns (stream Order) {} // 客户端推送 rpc ClientStream(stream OrderApiCreate) returns (Order) {} // 双向推送 rpc BdStream(stream OrderApiCreate) returns (stream Order) {} } message OrderApiCreate{ int64 order_id = 1; repeated int64 user_id = 2; string remark = 3; repeated int32 reason_id = 4; }
使用起来也是非常简单的,只需要定义自己的 .proto
文件,便可用命令行工具生成对应语言的 SDK。
具体可以参考官方文档:grpc.io/docs/langua…
调用
protoc --go_out=. --go_opt=paths=source_relative \ --go-grpc_out=. --go-grpc_opt=paths=source_relative \ test.proto
网络异常,图片无法展示
|
生成代码之后编写服务端就非常简单了,只需要实现生成的接口即可。
func (o *Order) Create(ctx context.Context, in *v1.OrderApiCreate) (*v1.Order, error) { // 获取 metadata md, ok := metadata.FromIncomingContext(ctx) if !ok { return nil, status.Errorf(codes.DataLoss, "failed to get metadata") } fmt.Println(md) fmt.Println(in.OrderId) return &v1.Order{ OrderId: in.OrderId, Reason: nil, }, nil }
网络异常,图片无法展示
|
客户端也非常简单,只需要依赖服务端代码,创建一个 connection
然后就和调用本地方法一样了。
这是经典的 unary
(一元)调用,类似于 http 的请求响应模式,一个请求对应一次响应。
网络异常,图片无法展示
|