grpc介绍
grpc是一个高性能、通用的开源rpc框架,其由google主要面向移动应用开发并基于http/2标准协议而设计,基于Protobuf(protocol buffers)序列化协议开发,且支持众多开发语言。
gRPC提供了一种简单的方法来精确地定义服务和为iOS、Android和后台支持服务自动生成可靠性很强的客户端功能库。
客户端充分利用高级流和链接功能,从而有助于降低带宽,降低tcp链接次数,节省CPU使用和电池寿命。
grpc具有一下重要特征:
- 强大的IDL特性
GRPC使用protobuf来定义服务,protobuf是由google开发的一种数据序列化协议,性能出众,得到广泛使用。 - 支持多种语言
支持C++、Java、Go、Python、Ruby、C#、Node.js、Android Java、Objective-C、PHP等编程语言。 - 基于http/2标准设计
gRPC已经应用在Google的云服务和对外提供的API中。
我们以 gRPC-go 为例介绍一下gRPC的开发。
首先下载相应的库:
go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc
同时保证按照Protocol Buffers v3 编译器到你的开发环境中(protoc)。
定义你的protobuf文件 (helloworld.proto):
syntax = "proto3";
package proto;
option go_package = "my_grpc/proto";
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
service Greeter {
rpc SayHello(HelloRequest) returns (HelloReply){}
}
这个文件定义了一个Greeter服务,它有一个SayHello方法,这个方法接收一个Request,返回一个Response。
然后我们可以编译这个proto文件,生成服务器和客户端的stub:
# 生成helloword.pb.go文件
protoc --go_out=./pbfiles --go_opt=paths=source_relative -I proto .\proto\helloworld.proto
# 生成helloword_grpc.pb.go文件
protoc --go-grpc_out=./pbfiles --go-grpc_opt=paths=source_relative -I proto .\proto\helloworld.proto
因为上面我们安装了proto和protoc-gen-go,所以protoc可以生成响应的Go代码。
然后我们就可以利用这个生成的代码创建服务器代码和客户端代码了。
服务器端的代码如下:
package main
import (
"context"
"google.golang.org/grpc"
"my_grpc/pbfiles"
"net"
)
const (
port = ":8000"
)
type server struct {
pbfiles.UnimplementedGreeterServer
}
func (s *server) SayHello(ctx context.Context, in *pbfiles.HelloRequest) (*pbfiles.HelloReply, error) {
return &pbfiles.HelloReply{Message: "hello" + in.Name}, nil
}
func main() {
// 创建监听套接字
listen, _ := net.Listen("tcp", port)
// 创建grpc服务
gServer := grpc.NewServer()
// 将server注册到grpc服务中
pbfiles.RegisterGreeterServer(gServer, &server{})
// 开启服务
_ = gServer.Serve(listen)
}
客户端的测试代码如下:
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"my_grpc/pbfiles"
)
const (
address = ":8000"
)
func main() {
clientConn, _ := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials()))
greeterClient := pbfiles.NewGreeterClient(clientConn)
helloReply, _ := greeterClient.SayHello(context.Background(), &pbfiles.HelloRequest{Name: "王五"})
fmt.Println(helloReply)
}