grpc

http://doc.oschina.net/grpc
gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.



gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。



https://www.grpc.io/docs/



$ go get -u github.com/grpc/grpc-go/examples/helloworld/greeter_client
go: downloading github.com/grpc/grpc-go v1.34.0
go: downloading github.com/grpc/grpc-go/examples v0.0.0-20210109011638-fb40d83340e8
go: found github.com/grpc/grpc-go/examples/helloworld/greeter_client in github.com/grpc/grpc-go/examples v0.0.0-20210109011638-fb40d83340e8
go get: github.com/grpc/grpc-go/examples@v0.0.0-20210109011638-fb40d83340e8: parsing go.mod:
module declares its path as: google.golang.org/grpc/examples
but was required as: github.com/grpc/grpc-go/examples



$ go get -u github.com/grpc/grpc-go/examples/helloworld/greeter_server
go: found github.com/grpc/grpc-go/examples/helloworld/greeter_server in github.com/grpc/grpc-go/examples v0.0.0-20210109011638-fb40d83340e8
go get: github.com/grpc/grpc-go/examples@v0.0.0-20210109011638-fb40d83340e8: parsing go.mod:
module declares its path as: google.golang.org/grpc/examples
but was required as: github.com/grpc/grpc-go/examples

$ git clone https://github.com/grpc/grpc



Go
为了生成客户端和服务端接口,运行 protocol buffer 编译器:
protoc -I ../protos ../protos/helloworld.proto –go_out=plugins=grpc:helloworld



Node.js
Node.js库从运行时加载的 .proto 文件动态生成服务描述和客户端存根的定义,所以使用此语言时没必要生成任何特殊代码。而是在例子客户端和服务端里,我们 require gRPC 库,然后用它的 load() 方法:



var grpc = require(‘grpc’);
var hello_proto = grpc.load(PROTO_PATH).helloworld;



http://doc.oschina.net/grpc?t=58008



服务定义
正如其他 RPC 系统,gRPC 基于如下思想:定义一个服务, 指定其可以被远程调用的方法及其参数和返回类型。gRPC 默认使用 protocol buffers 作为接口定义语言,来描述服务接口和有效载荷消息结构。如果有需要的话,可以使用其他替代方案。



service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}



message HelloRequest {
required string greeting = 1;
}



message HelloResponse {
required string reply = 1;
}
gRPC 允许你定义四类服务方法:



单项 RPC,即客户端发送一个请求给服务端,从服务端获取一个应答,就像一次普通的函数调用。
rpc SayHello(HelloRequest) returns (HelloResponse){
}
服务端流式 RPC,即客户端发送一个请求给服务端,可获取一个数据流用来读取一系列消息。客户端从返回的数据流里一直读取直到没有更多消息为止。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){
}
客户端流式 RPC,即客户端用提供的一个数据流写入并发送一系列消息给服务端。一旦客户端完成消息写入,就等待服务端读取这些消息并返回应答。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {
}
双向流式 RPC,即两边都可以分别通过一个读写数据流来发送一系列消息。这两个数据流操作是相互独立的,所以客户端和服务端能按其希望的任意顺序读写,例如:服务端可以在写应答前等待所有的客户端消息,或者它可以先读一个消息再写一个消息,或者是读写相结合的其他方式。每个数据流里消息的顺序会被保持。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){
}



http://doc.oschina.net/grpc?t=60133
go get google.golang.org/grpc



cd $GOPATH/src/google.golang.org/grpc/examples/route_guide



https://github.com/grpc/grpc-go/blob/master/README.md



https://github.com/grpc/grpc/
https://developers.google.com/protocol-buffers/docs/proto3



$ protoc –go_out=plugins=grpc:. route_guide.proto
protoc-gen-go: program not found or is not executable
Please specify a program using absolute path or make sure the program is available in your PATH system variable
–go_out: protoc-gen-go: Plugin failed with status code 1.



n$ go get -u github.com/golang/protobuf/protoc-gen-go
go: downloading github.com/golang/protobuf v1.4.3
go: found github.com/golang/protobuf/protoc-gen-go in github.com/golang/protobuf v1.4.3
go: github.com/golang/protobuf upgrade => v1.4.3
go: google.golang.org/protobuf upgrade => v1.25.0



$ ln -s ~/go/bin/protoc-gen-go /usr/local/bin/



$ protoc –go_out=plugins=grpc:. ./route_guide.proto



$ tree
.
|__route_guide.proto
|
go.mod
|
go.sum
|
github.com
| |
grpc
| | |
__route_guide.pb.go



$ protoc –go_out=plugins=grpc:. ./route_guide.proto
2021/01/09 22:20:37 WARNING: Deprecated use of ‘go_package’ option without a full import path in “route_guide.proto”, please specify:
option go_package = “.;grpc”;
A future release of protoc-gen-go will require the import path be specified.



option go_package = “github.com/grpc”;
=>
option go_package = “../../github.com/grpc”;



$ tree
.
|__route_guide.proto
|
go.mod
|
route_guide.pb.go
|
__go.sum



route_guide.pb.go
这些包括:



所有用于填充,序列化和获取我们请求和响应消息类型的 protocol buffer 代码
一个为客户端调用定义在RouteGuide服务的方法的接口类型(或者 存根 )
一个为服务器使用定义在RouteGuide服务的方法去实现的接口类型(或者 存根 )



$ go run server/server.go



$ go run client/client.go



启动服务器
一旦我们实现了所有的方法,我们还需要启动一个gRPC服务器,这样客户端才可以使用服务。下面这段代码展示了在我们RouteGuide服务中实现的过程:



flag.Parse()
lis, err := net.Listen(“tcp”, fmt.Sprintf(“:%d”, *port))
if err != nil {
log.Fatalf(“failed to listen: %v”, err)
}
grpcServer := grpc.NewServer()
pb.RegisterRouteGuideServer(grpcServer, &routeGuideServer{})
… // determine whether to use TLS
grpcServer.Serve(lis)
为了构建和启动服务器,我们需要:



使用 lis, err := net.Listen(“tcp”, fmt.Sprintf(“:%d”, *port)) 指定我们期望客户端请求的监听端口。
使用grpc.NewServer()创建 gRPC 服务器的一个实例。
在 gRPC 服务器注册我们的服务实现。
用服务器 Serve() 方法以及我们的端口信息区实现阻塞等待,直到进程被杀死或者 Stop() 被调用。



创建存根
为了调用服务方法,我们首先创建一个 gRPC channel 和服务器交互。我们通过给 grpc.Dial() 传入服务器地址和端口号做到这点,如下:



conn, err := grpc.Dial(*serverAddr)
if err != nil {

}
defer conn.Close()
你可以使用 DialOptions 在 grpc.Dial 中设置授权认证(如, TLS,GCE认证,JWT认证),如果服务有这样的要求的话 —— 但是对于 RouteGuide 服务,我们不用这么做。



一旦 gRPC channel 建立起来,我们需要一个客户端 存根 去执行 RPC。我们通过 .proto 生成的 pb 包提供的 NewRouteGuideClient 方法来完成。



client := pb.NewRouteGuideClient(conn)
调用服务方法
现在让我们看看如何调用服务方法。注意,在 gRPC-Go 中,RPC以阻塞/同步模式操作,这意味着 RPC 调用等待服务器响应,同时要么返回响应,要么返回错误。



简单 RPC
调用简单 RPC GetFeature 几乎是和调用一个本地方法一样直观。



feature, err := client.GetFeature(context.Background(), &pb.Point{409146138, -746188906})
if err != nil {

}



http://doc.oschina.net/grpc?t=60133



https://zhuanlan.zhihu.com/p/148139089



https://www.cnblogs.com/awesomeHai/p/liuhai.html



https://chenjiehua.me/python/grpc-quick-start.html


Category golang