gRPC是什么?
gRPC是一个高性能、开源、通用的RPC框架,面向移动和HTTP/2设计 | |
支持多语言:C++、C#、Dart、Go、Java、Node.js、Objective-c、PHP、Python、Ruby | |
特点:HTTP/2、Protobuf、客户端、服务的基于同一份IDL、移动网络的良好支持、支持多语言 |
图解调用过程:
1、客户端(gRPC Stub)发起发起 RPC 调用
2、对请求参数使用 Protobuf 进行对象序列化(IDL)
3、服务端(gRPC Server)接收到请求后,解码请求体,进行业务逻辑处理并返回
4、对响应结果使用 Protobuf 进行对象序列化(IDL)
5、客户端接受到服务端响应,解码请求体,返回响应结果
入门示例
首先需要安装
gRPC:
go get -u google.golang.org/grpc
Protocol Buffers v3
wget https://github.com/google/protobuf/releases/download/v3.5.1/protobuf-all-3.5.1.zip | |
unzip protobuf-all-3.5.1.zip | |
cd protobuf-3.5.1/ | |
./configure | |
make | |
make install |
验证安装是否成功:
protoc --version
Protoc Plugin:
go get -u github.com/golang/protobuf/protoc-gen-go
首先我们新建 hello.proto
syntax = "proto3"; | |
package proto; | |
option go_package = "/"; | |
service HelloService { | |
rpc Hello(HelloRequest) returns (HelloResponse) {} | |
} | |
message HelloRequest { | |
string request = 1; | |
} | |
message HelloResponse { | |
string response = 1; | |
} |
其中 option go_package
是指定go包,不然执行编译时会报错:
protoc-gen-go: unable to determine Go import path for "hello.proto"
然后再该文件目录下执行:
protoc --go_out=plugins=grpc:. *.proto
该命令会在目录下生成 hello.pb.go 文件
新建 server.go 文件,并写入以下内容
package main | |
import ("context""google.golang.org/grpc""log""net""proto" | |
) | |
type HelloService struct {} | |
func (s *HelloService) Hello(ctx context.Context, r *proto.HelloRequest) (*proto.HelloResponse, error) { | |
return &pb.HelloResponse{Response: "Hello " + r.GetRequest()}, nil | |
} | |
const PORT = "8088" | |
func main() { | |
server := grpc.NewServer() | |
proto.RegisterHelloServiceServer(server, &HelloService{}) | |
lis, err := net.Listen("tcp", ":"+PORT)if err != nil { | |
log.Fatalf("net.listen err: %v", err)} | |
server.Serve(lis) | |
} |
新建client.go文件,并写入以下内容:
package main | |
import ("context""google.golang.org/grpc""proto""log") | |
const PORT = "8088" | |
func main() { | |
conn, err := grpc.Dial(":" + PORT, grpc.WithInsecure())if err != nil { | |
log.Fatalf("grpc.Dial err: %v", err)}defer conn.Close() | |
client := proto.NewHelloServiceClient(conn) | |
resp, err := client.Hello(context.Background(), &proto.HelloRequest{ | |
Request: "gRPC",})if err != nil { | |
log.Fatalf("client.Search err:%v", err)} | |
log.Printf("resp: %s", resp.GetResponse()) | |
} |
启动server
go run server.go
启动client
go run client.go
输出:
$ go run client.go | |
2021/04/25 15:07:27 resp: Hello gRPC |