在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-go
和protoc-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.go
和 proto/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_FOUND
、INVALID_ARGUMENT
),可以用來表示不同類型的錯誤。
3. 中介軟體和攔截器
利用gRPC 中間件可以在請求前後加入邏輯,例如日誌記錄、監控和認證。
4. 使用gRPC Gateway
如果需要RESTful 接口,可以使用gRPC Gateway 自動將gRPC 轉換為REST API。這在微服務架構中尤其有用。
七、總結
本文介紹如何在Golang 中使用gRPC 實作RPC 服務,包括環境建置、服務定義、伺服器和用戶端實作。 gRPC 以其高效能和易用性成為現代微服務架構的熱門選擇。希望這篇文章能幫助你快速上手gRPC,並在實際專案中應用。透過不斷學習和實踐,你可以更深入地理解gRPC 的功能和優勢。
如有疑問或建議,請在下方留言。感謝閱讀!