Golang RPC 之 gRPC
阿新 • • 發佈:2022-05-04
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 介面定義成功