轉載請注明來自ChenJiehua的《GRPC快速入門》
GRPC是一個高性能、通用的開源RPC框架,基於HTTP/2協議標准和Protobuf序列化協議開發,支持眾多的開發語言。
概述
在GRPC框架中,客戶端可以像調用本地對象一樣直接調用位於不同機器的服務端方法,如此我們就可以非常方便的創建一些分布式的應用服務。
在服務端,我們實現了所定義的服務和可供遠程調用的方法,運行一個gRPC server來處理客戶端的請求;在客戶端,gRPC實現了一個stub(可以簡單理解為一個client),其提供跟服務端相同的方法。
gRPC使用protocol buffers作為接口描述語言(IDL)以及底層的信息交換格式,一般情況下推薦使用 proto3因為其能夠支持更多的語言,並減少一些兼容性的問題。
簡單示例如下:
// 定義了一個服務 Greeter service Greeter { // 定義方法 SayHello rpc SayHello (HelloRequest) returns (HelloReply) {} } // request message HelloRequest { string name = 1; } // response message HelloReply { string message = 1; }
gRPC使用 protoc 和一個插件來將proto定義的內容生成客戶端/服務端的代碼。
Proto定義
helloworld.proto
syntax = "proto3"; option java_multiple_files = true; option java_package = "io.grpc.examples.helloworld"; option java_outer_classname = "HelloWorldProto"; package helloworld; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings message HelloReply { string message = 1; }
Go示例
安裝grpc和protobuf
1、gRPC要求 Go 版本 >= 1.6
2、安裝 gRPC:
$ go get -u -v google.golang.org/grpc
3、安裝 Protocol Buffers v3:
從github下載預編譯的protoc,然后安裝 protoc-gen-go:
$ go get -v -u github.com/golang/protobuf/protoc-gen-go
生成 gRPC代碼
$ protoc -I. --go_out=plugins=grpc:. helloworld.proto
Server 代碼
server.go
package main import ( "log" "net" "golang.org/x/net/context" "google.golang.org/grpc" pb "google.golang.org/grpc/examples/helloworld/helloworld" "google.golang.org/grpc/reflection" ) const ( port = ":50051" ) // server is used to implement helloworld.GreeterServer. type server struct{} // SayHello implements helloworld.GreeterServer func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { return &pb.HelloReply{Message: "Hello " + in.Name}, nil } func main() { lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterGreeterServer(s, &server{}) // Register reflection service on gRPC server. reflection.Register(s) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }
Client 代碼
client.go
package main import ( "log" "os" "time" "golang.org/x/net/context" "google.golang.org/grpc" pb "google.golang.org/grpc/examples/helloworld/helloworld" ) const ( address = "localhost:50051" defaultName = "world" ) func main() { // Set up a connection to the server. conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() c := pb.NewGreeterClient(conn) // Contact the server and print out its response. name := defaultName if len(os.Args) > 1 { name = os.Args[1] } ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("Greeting: %s", r.Message) }
Python示例
安裝grpc和protobuf
1、新建個虛擬環境:
$ pip install virtualenv $ virtualenv venv $ source venv/bin/activate $ pip install -U pip
2、在虛擬環境中安裝grpc和protobuf:
$ pip install grpcio
3、安裝 grpc tools:
python的grpc tools包含了protoc及其插件,用來生成客戶端和服務端代碼
$ pip install grpcio-tools
4、安裝 grpc reflection:
grpc reflection 使得服務端支持 grpc_cli 進行調試
$ pip install grpcio-reflection
生成 gRPC 代碼
$ python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. helloworld.proto
Server 代碼
server.py
"""The Python implementation of the GRPC helloworld.Greeter server.""" from concurrent import futures import time import grpc from grpc.reflection.v1alpha import reflection<br> import helloworld_pb2 import helloworld_pb2_grpc _ONE_DAY_IN_SECONDS = 60 * 60 * 24 class Greeter(helloworld_pb2_grpc.GreeterServicer): def SayHello(self, request, context): return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) def serve(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) reflection.enable_server_reflection([h.service_name() for h in server._state.generic_handlers], server) server.add_insecure_port('[::]:50051') server.start() try: while True: time.sleep(_ONE_DAY_IN_SECONDS) except KeyboardInterrupt: server.stop(0) if __name__ == '__main__': serve()
Client 代碼
client.py
"""The Python implementation of the GRPC helloworld.Greeter client.""" from __future__ import print_function import grpc import helloworld_pb2 import helloworld_pb2_grpc def run(): channel = grpc.insecure_channel('localhost:50051') stub = helloworld_pb2_grpc.GreeterStub(channel) response = stub.SayHello(helloworld_pb2.HelloRequest(name='you')) print("Greeter client received: " + response.message) if __name__ == '__main__': run()
grpc_cli命令行工具
為了使用 grpc_cli ,我們需要從源碼進行安裝。
1、從github獲取源碼:
$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
$ cd grpc
$ git submodule update --init
2、編譯 grpc_cli:
# Linux下需要 gflags $ sudo apt-get install libgflags-dev $ make grpc_cli
3、使用 grpc_cli:
# 查看所有的服務 $ grpc_cli ls localhost:50051 # 查看 Greeter 服務的詳細信息 $ grpc_cli ls localhost:50051 helloworld.Greeter -l # 查看 Greeter.SayHello 方法的詳細信息 $ grpc_cli ls localhost:50051 helloworld.Greeter.SayHello -l # 遠程調用 $ grpc_cli call localhost:50051 SayHello "name: 'gRPC CLI'"
參考:
- https://grpc.io/docs/guides/index.html
- https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md
- 轉載請注明來自ChenJiehua的《GRPC快速入門》