在Golang 中使用gRPC + Protocol Buffers 實現高效率的RPC 服務

在Golang 中使用gRPC + Protocol Buffers 實現高效率的RPC 服務

引言

隨著微服務架構的流行,遠端過程呼叫(RPC)在現代應用程式中變得越來越重要。 gRPC 是Google 開發的一種高效能、開源和通用的RPC 框架,它使用HTTP/2 作為傳輸協議,支援多種語言,包括Go。本文將詳細介紹如何在Golang 中使用gRPC 實現RPC 服務,包括環境建構、基本概念、程式碼範例和一些最佳實務。

一、環境搭建

1. 安裝Go

首先,確保你已經安裝和部署了Go 環境。可以透過以下命令檢查:

go version

如果以安裝Go環境,可以看到如上圖Go當前版本信息,我當前版本為go1.23.1,為最新版本,如果尚未安裝,請訪問 Go 官方網站 依自己需求下載並安裝。

2. 安裝grpc 和Protocol Buffers

由於gRPC 預設以 Protocol Buffers 協定進行資料傳輸,Protocol Buffers 是由google開源的結構化資料系列化協議,我們這裡後續將藉助 Protocol Buffers 定義和約束我們的服務,所以接下來我們需要安裝grpc 和 Protocol Buffers 相關的庫和插件。Protocol Buffers 基本介紹及基本文法

  • 安裝gRPC 和Protocol Buffers Go 外掛:

    go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

    go install 指令會將Go相關的插件安裝在GO安裝目錄下的bin目錄中,這裡我們需要確保將 protoc-gen-goprotoc-gen-go-grpc 的可執行檔路徑新增至系統可執行檔 $PATH 中.

  • 將Go 的bin 目錄加入系統執行目錄 /usr/local/bin:

    export PATH=$PATH:$(go env GOPATH)/bin

    可以將上述指令加入你的~/.bashrc 或~/.bash_profile 檔案中,以便每次登入時自動載入。

  • 檢查插件是否安裝成功:

    protoc-gen-go --version protoc-gen-go-grpc --version

    如果安裝成功這裡會輸出對應的插件版本資訊。

3. 安裝Protocol Buffers Compiler

然後,下載並安裝Protocol Buffers Compiler(protoc)。可以從 GitHub Releases 下載適合你作業系統的版本,並將其路徑加入 $PATH

  • 然後使用wget 下載。以28.2 版本為例:

    wget https://github.com/protocolbuffers/protobuf/releases/download/v28.2/protoc-28.2-linux-x86_64.zip
  • 解壓縮下載的zip 檔:

    unzip protoc-28.2-linux-x86_64.zip -d protoc
  • 移動檔案並新增至系統可執行目錄 /usr/local/bin:

    sudo mv protoc/bin/protoc /usr/local/bin/ sudo mv protoc/include/* /usr/local/include/
  • 檢查protoc 是否安裝成功:

    protoc --version

    如果輸出 libprotoc 28.2, 說明安裝成功。

4. 建立專案結構

建立一個新的Go 項目,並設定以下目錄結構:

grpc-example/ ├── server/ │ └── main.go ├── proto/ │ └── example.proto └── client/ └── main.go

目錄結構說明

  • server: grpc 服務端程式碼目錄
  • proto: grpc 服務Protocol Buffers
  • client: grpc 客戶端程式碼目錄

二、定義gRPC 服務

proto/example.proto 中定義我們的gRPC 服務和訊息格式:

syntax = "proto3"; package example; // 定義服務service Greeter { // 定義一個RPC 方法rpc SayHello(HelloRequest) returns (HelloReply); } // 定義Request 訊息message HelloRequest { string name = 1; } // 定義Request 訊息message HelloRequest { string name = 1; } // 定義Response 訊息message HelloReply { string message = 1; }

這裡我們透過 Protocol Buffers 定義了我們的服務以及服務請求和回覆的結構體。具體 Protocol Buffers 相關的資訊和文法,我們在下一篇文章中具體介紹。

1. 產生Go 程式碼

grpc-example 目錄中,執行以下指令,透過protoc產生Go 程式碼:

protoc --go_out=. --go-grpc_out=. proto/example.proto

上面命令會生成 proto/example.pb.goproto/example_grpc.pb.go 文件,文件中包含我們在 poroto 文件中定義的服務的結構體和方法。

三、實現gRPC 伺服器

server/main.go 中實作gRPC 伺服器:

package main import ( "context" "log" "net" "google.golang.org/grpc" pb "grpc-example/proto" ) // 伺服器結構type server struct { pb.UnimplementedGreeterServer } // 實作SayHello 方法func (s *server) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) { log.Printf("Received: %v", req.Name) return &pb.HelloReply{Message: "Hello " + req.Name}, nil } func main() { // 監聽埠lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen : %v", err) } // 建立gRPC 伺服器grpcServer := grpc.NewServer() pb.RegisterGreeterServer(grpcServer, &server{}) log.Println("Starting gRPC server on port :50051") pc : Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }

程式碼解釋

  • server 結構體:實現了 GreeterServer 接口。
  • SayHello 方法:處理傳入的請求並回傳回應。
  • main 函數:設定TCP 監聽和gRPC 伺服器並啟動。

四、實現gRPC 客戶端

client/main.go 中實作gRPC 客戶端:

package main import ( "context" "log" "time" "google.golang.org/grpc" pb "grpc-example/proto" ) func main() { // 連接到gRPC 伺服器conn, err := grpc.Dial ("localhost:50051", grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() // 建立客戶端client := pb. NewGreeterClient(conn) // 建立上下文,設定超時ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() // 傳送請求response, err := client.SayHello(ctx, &pbb .HelloRequest{Name: "World"}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("Greeting: %s", response.Message) }

程式碼解釋

  • grpc.Dial:連接到gRPC 伺服器。
  • NewGreeterClient:建立客戶端。
  • SayHello:調用遠端過程並獲取響應。

五、運行gRPC 服務

1. 啟動gRPC 伺服器

grpc-example/server 目錄中運作:

go run main.go

2. 啟動gRPC 客戶端

grpc-example/client 目錄中運作:

go run main.go

客戶端收到訊息如下:

Greeting: Hello World

六、最佳實踐

1. 使用Protobuf 進行版本控制

使用Protobuf 進行版本控制非常重要。可以透過新增欄位而不刪除現有欄位來實現向後相容性。

2. 錯誤處理

確保在伺服器和用戶端中對錯誤進行適當處理。 gRPC 提供了一些內建的錯誤碼(如 NOT_FOUNDINVALID_ARGUMENT),可以用來表示不同類型的錯誤。

3. 中介軟體和攔截器

利用gRPC 中間件可以在請求前後加入邏輯,例如日誌記錄、監控和認證。

4. 使用gRPC Gateway

如果需要RESTful 接口,可以使用gRPC Gateway 自動將gRPC 轉換為REST API。這在微服務架構中尤其有用。

七、總結

本文介紹如何在Golang 中使用gRPC 實作RPC 服務,包括環境建置、服務定義、伺服器和用戶端實作。 gRPC 以其高效能和易用性成為現代微服務架構的熱門選擇。希望這篇文章能幫助你快速上手gRPC,並在實際專案中應用。透過不斷學習和實踐,你可以更深入地理解gRPC 的功能和優勢。

如有疑問或建議,請在下方留言。感謝閱讀!

暫無評論

發送評論 編輯評論

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ°Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
顏文字
Emoji
小恐龍
花!
上一篇
下一篇