1. 程式人生 > 其它 >Golang RPC 之 gRPC

Golang RPC 之 gRPC

gRPC 簡介:

gRPC 是一款高效能、開源的 RPC 框架,產自 Google,基於 ProtoBuf 序列化協議進行開發,支援多種語言(Golang、Python、Java等),本篇只介紹 Golang 的 gRPC 使用。因為 gRPC 對 HTTP/2 協議的支援使其在 Android、IOS 等客戶端後端服務的開發領域具有良好的前景。gRPC 提供了一種簡單的方法來定義服務,同時客戶端可以充分利用 HTTP/2 stream 的特性,從而有助於節省頻寬、降低 TCP 的連線次數、節省CPU的使用等。

安裝:

  • gRPC 的安裝:
$ go get -u google.golang.org/grpc
  • 因為 gRPC 是基於 protobuf 實現的介面序列化,所以也要安裝 protobuf: 安裝及簡介教程(Golang 序列化之 ProtoBuf)。

實踐:

下面我們使用 gRPC 定義一個介面,該介面實現對傳入的資料進行大寫的格式化處理。

1. 建立專案 golang Demo 工程:

  • client目錄下的 main.go 實現了客戶端用於傳送資料並列印接收到 server 端處理後的資料
  • server 目錄下的 main.go 實現了服務端用於接收客戶端傳送的資料,並對資料進行大寫處理後返回給客戶端
  • example 包用於編寫 proto 檔案並生成 data 介面

2. 定義 gRPC 介面:

syntax = "proto3";
package example;
service FormatData {
 rpc DoFormat(Data) returns (Data){}
}
message Data {
 string text = 1;
}

3. 編譯 protobuf:

$ protoc -I=. --go_out=plugins=grpc:. . // 在 example 目錄中執行編譯,會生成:data.pb.go

4. 實現 server 端:

package main
import (
 "Demo/example"
 "net"
 "google.golang.org/grpc"
 "google.golang.org/grpc/reflection"
 "golang.org/x/net/context"
 "strings"
 "log"
)
// 定義監聽地址
const (
 HOST string = "localhost"
 PORT string = "8080"
)
// 定義介面
type FormatData struct{}
func (fd *FormatData) DoFormat(ctx context.Context, in *example.Data) (out *example.Data, err error) {
 str := in.Text
 out = &example.Data{Text: strings.ToUpper(str)}
 return out, nil
}
// 直接在 main 方法中註冊介面
func main() {
 listener, err := net.Listen("tcp", HOST+":"+PORT)
 if err != nil {
     log.Fatalln("faile listen at: " + HOST + ":" + PORT)
 } else {
     log.Println("Demo server is listening at: " + HOST + ":" + PORT)
 }
 rpcServer := grpc.NewServer()
 example.RegisterFormatDataServer(rpcServer, &FormatData{})
 reflection.Register(rpcServer)
 if err = rpcServer.Serve(listener); err != nil {
     log.Fatalln("faile serve at: " + HOST + ":" + PORT)
 }
}

5. 實現 client 端:

package main
import (
 "google.golang.org/grpc"
 "log"
 "Demo/example"
 "golang.org/x/net/context"
)
// 定義請求地址
const (
 ADDRESS string = "localhost:8080"
)
// main 方法實現對 gRPC 介面的請求
func main() {
 conn, err := grpc.Dial(ADDRESS, grpc.WithInsecure())
 if err != nil {
     log.Fatalln("Can't connect: " + ADDRESS)
 }
 defer conn.Close()
 client := example.NewFormatDataClient(conn)
 resp,err := client.DoFormat(context.Background(), &example.Data{Text:"hello,world!"})
 if err != nil {
     log.Fatalln("Do Format error:" + err.Error())
 }
 log.Println(resp.Text)
}

6. 執行驗證結果:

  • 先啟動 server,之後再執行 client
  • client 側控制檯如果列印的結果為: HELLO,WORLD! ,證明 gRPC 介面定義成功