微服务系列(二)GRPC的介绍与安装 1.GPRC简介
GRPC是Google公司基于Protobuf开发的跨语言的开源RPC框架。GRPC基于HTTP/2协议设计,可以基于一个HTTP/2链接提供多个服务,对于移动设备更加友好。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.
在 gRPC里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC系统类似, gRPC也是基于以下理念:
定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。
在服务端实现这个接口,并运行一个 gRPC服务器来处理客户端调用。
在客户端拥有一个存根能够像服务端一样的方法。 gRPC客户端和服务端可以在多种环境中运行和交互 -从 google内部的服务器到你自己的笔记本,并且可以用任何 gRPC支持的语言 来编写。
所以,你可以很容易地用 Java创建一个 gRPC服务端,用 Go、 Python、Ruby来创建客户端。此外, Google最新 API将有 gRPC版本的接口,使你很容易地将 Google的功能集成到你的应用里。
参考资料
gRPC 官方文档中文版:?t=60133
gRPC官网:https://grpc.io
再详细了解使用GRPC之前先来了解一下上面定义中的一些关键词。
首先我们来看一下HTTP/2是什么内容?
其实本质上就是http2.0版本,http目前为止主要有四个版本,分别为http1.0、http1.1、http2.0、https。
http1.0是最原始的版本,不支持持久连接,效率也比较低
http1.1针对http1.0版本做了优化,可以连接一次,多次使用,效率比http1.0高
http2.0实现了多路复用,对http1.1再次进行了优化。http2.0也被称为下一代http协议,是在2013年8月进行首次测试,所以现在用的不是很广。
https其实是在http协议上多加了一层SSL协议,具体如下图:
所以本质上,http1.0、http1.1、http2.0都可以添加SSL协议。
2. grpc环境安装
官方推荐安装方法:
go get -u -v google.golang.org/grpc但是由于墙原因,不能直接访问google官网,所以只能曲线救国了
通过github下载各种依赖库,然后配置。
git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc git clone https://github.com/golang/net.git $GOPATH/src/golang.org/x/net git clone https://github.com/golang/text.git $GOPATH/src/golang.org/x/text git clone https://github.com/google/go-genproto.git $GOPATH/src/google.golang.org/genproto cd $GOPATH/src/ go install google.golang.org/grpc网络畅通可以用上述方法,但如果网速较慢,我们也可以选择离线安装方法。
用x.zip和google.golang.org.zip两个离线包来安装。
#将x.zip 解压到 $GOPATH/src/golang.org/x 目录下 $ unzip x.zip -d $GOPATH/src/golang.org/x #将google.golang.org.zip 解压到 $GOPATH/src/google.golang.org 目录下 $ unzip google.golang.org.zip -d $GOPATH/src/google.golang.org #然后进入到$GOPATH/src/google.golang.org/grpc下面执行go install $ go install点击此处获取两个离线压缩包
3.GRPC使用如果从Protobuf的角度看,GRPC只不过是一个针对service接口生成代码的生成器。接着我们来学习一下GRPC的用法。这里我们创建一个简单的proto文件,定义一个HelloService接口:
文件名称为person.proto
syntax = "proto3"; package pb; // 后期生成go的文件包名 option go_package = "../pb"; // go 1.14后需要指定导出的路径 // 消息体 -- 一个package中,不允许定义同名的消息体 message Teacher { int32 age = 1; string name = 2; } // 定义服务 service SayName { rpc SayHello(Teacher) returns (Teacher); }对proto文件进行编译:
protoc --go_out=plugins=grpc:./ person.proto
编译后生成person.pb.go文件
GRPC插件会为服务端和客户端生成不同的接口:
//客户端接口 type SayNameClient interface { SayHello(ctx context.Context, in *Teacher, opts ...grpc.CallOption) (*Teacher, error) } //服务器接口 type SayNameServer interface { SayHello(context.Context, *Teacher) (*Teacher, error) }我们接着可以基于他们给的服务端接口重新实现SayHello服务:
// 定义一个结构体 不一定非得是Teacher type Children struct { } // 接口去绑定类方法 func (c *Children) SayHello(ctx context.Context,t *pb.Teacher) (*pb.Teacher, error) { t.Name += "is teaching" return t,nil }GRPC的启动流程和RPC的启动流程类似,代码如下:
func main(){ // 1. 初始一个grpc对象 grpcServer := grpc.NewServer() // 2.注册服务 pb.RegisterSayNameServer(grpcServer,new(Children)) // 3.设置监听并建立连接,指定IP port listener ,err := net.Listen("tcp","127.0.0.1:8080") if err!=nil{ fmt.Printf("监听失败:%v",err) return } defer listener.Close() fmt.Println("正在监听127.0.0.1:8080 ...") // 4.启动服务 ... Serve() grpcServer.Serve(listener) }