grpc初使用全攻略

grpc裏的客戶端可以像調用本地對象一樣,直接調用另一臺機器上服務端的應用

一、什麼是gRPC

  • 在服務端實現一個接口,定義一個服務,指定能被遠程調用的方法,並運行一個gRPC服務來處理客戶端調用
  • 用proto files創建gRPC服務,用protocol buffers消息類型定義方法參數和返回類型。

1. 支持的語言:

  • Go、python、ruby、C++、Java、node.js、C#、PHP、Android Java、Objective-C

2. protocol buffers

  • 默認消息類型:protocol buffers(Google開源的一套結構數據序列化機制)
  • 也可用json
  • 現在常用proto3,因爲proto3可以使用grpc支持的全部範圍的語言,並且能避免proto2客戶端與proto3服務端交互時出現的兼容問題

二、使用

1. 分爲三步

  1. 通過protocol buffers定義一個RPC服務
  2. 創建一個實現這個接口的服務端
  3. 訪問服務端

2. python實現

1) 定義一個服務

  • helloworld.proto

}

2) 生成grpc代碼

  • 用定義的服務,使用protocol buffer編譯器protoc生成創建應用所需的特定客戶端和服務端代碼
python

protoc -I …/…/protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=which grpc_python_plugin …/…/protos/helloworld.proto

  • 生成了helloworld_pb2.py
Go

protoc -I …/protos …/protos/helloworld.proto --go_out=plugins=grpc:helloworld

  • 生成了helloworld.pb.go

3)寫服務來訪問

python
  • greeter_server.py

    class Greeter(helloworld_pb2.BetaGreeterServicer)def SayHello(self, request, context)return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
    
  • 爲了返回給客戶端應答並且完成調用:

  1. 用我們的激動人心的消息構建並填充一個在我們接口定義的 HelloReply 應答對象。
  2. 將 HelloReply 返回給客戶端。
Go
  • greeter_server/main.go 實現了 Greeter 服務所需要的行爲。
  • 正如你所見,服務器有一個 server 結構。它通過實現 sayHello 方法,實現了從 proto 服務定義生成的GreeterServer 接口:
// 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
}
  • 爲了返回給客戶端應答並且完成調用:
  1. 用我們的激動人心的消息構建並填充一個在我們接口定義的 HelloReply 應答對象。
  2. 將 HelloReply 返回給客戶端。

4) 服務端實現

  • 在這裏我們創建了合理的 gRPC 服務器,將我們實現的 Greeter 服務綁定到一個端口。
  • 然後我們啓動服務器:服務器準備好從 Greeter 服務客戶端接收請求
python
- greeter_server.py
```python
server = helloworld_pb2.beta_create_Greeter_server(Greeter())
server.add_insecure_port('[::]:50051')
server.start()
try:
  while True:
    time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
  server.stop()
```
go
  • greeter_server/main.go
    const (
      port = ":50051"
    )
    ...
    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{})
      s.Serve(lis)
    }
    

5) 寫一個客戶端

  • 用生成的代碼寫一個簡單的客戶程序來訪問我們在上邊創建的 Greeter 服務器
  • 連接服務器:
    • 需要創建一個 gRPC 頻道,指定我們要連接的主機名和服務器端口。然後我們用這個頻道創建存根實例
Python
  • 生成的 Python 代碼有一個根據頻道創建存根的幫助方法。
    channel = implementations.insecure_channel('localhost', 50051)
    stub = helloworld_pb2.beta_create_Greeter_stub(channel)
    ...
    
Go
const (
  address     = "localhost:50051"
  defaultName = "world"
)
func main() {
  // Set up a connection to the server.
  conn, err := grpc.Dial(address)
  if err != nil {
      log.Fatalf("did not connect: %v", err)
  }
  defer conn.Close()
  c := pb.NewGreeterClient(conn)
...
}
  • 在 gRPC Go 你是使用一個特殊的 Dial() 方法來創建頻道。

6) 調用RPC

  • 聯繫服務並獲得一個 greeting
  1. 創建並填充一個 HelloRequest 發送給服務。
  2. 我們用請求調用存根的 SayHello(),如果 RPC 成功,會得到一個填充的 HelloReply ,從其中我們可以獲得 greeting
python
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'), _TIMEOUT_SECONDS)
print "Greeter client received: " + response.message
Go
r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name})
if err != nil {
      log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.Message)

參考鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章