Go中跨語言實現(xiàn)傳輸?shù)姆椒ú襟E
gRPC 是 Google 開源的高性能 RPC 框架,基于 HTTP/2 協(xié)議和 Protocol Buffers(Protobuf)序列化,支持多語言、流式傳輸和企業(yè)級特性。與 RESTful API 相比,它性能更高、接口定義更規(guī)范,特別適合微服務(wù)架構(gòu)和跨語言服務(wù)調(diào)用。
| 概念 | 作用 | 說明 |
|---|---|---|
| Protocol Buffers(Protobuf) | 接口定義語言(IDL) | 用于定義服務(wù)接口和消息結(jié)構(gòu),跨語言、跨平臺,序列化性能極高 |
| Service(服務(wù)) | 定義 RPC 方法 | 在 .proto 文件中定義,包含方法名、請求消息、響應(yīng)消息 |
| Message(消息) | 定義數(shù)據(jù)結(jié)構(gòu) | 類似于 Go 的結(jié)構(gòu)體,用于定義請求和響應(yīng)的數(shù)據(jù)格式 |
| Unary RPC(一元 RPC) | 最簡單的 RPC 模式 | 客戶端發(fā)送一個請求,服務(wù)端返回一個響應(yīng),類似傳統(tǒng)的 HTTP 請求 |
| Server Streaming RPC(服務(wù)端流式) | 服務(wù)端流式返回 | 客戶端發(fā)送一個請求,服務(wù)端返回多個響應(yīng) |
| Client Streaming RPC(客戶端流式) | 客戶端流式發(fā)送 | 客戶端發(fā)送多個請求,服務(wù)端返回一個響應(yīng) |
| Bidirectional Streaming RPC(雙向流式) | 雙向流式傳輸 | 客戶端和服務(wù)端可以同時發(fā)送和接收多個消息 |
# 1. 安裝 protoc 編譯器 # Mac brew install protobuf # Linux apt install -y protobuf-compiler # 2. 安裝 Go 插件 go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest # 3. 安裝 gRPC 核心庫 go get google.golang.org/grpc
Unary RPC (一元 RPC)
grpc-demo/ ├── proto/ │ └── user.proto # Protobuf 定義文件 ├── server/ │ └── main.go # gRPC 服務(wù)端 ├── client/ │ └── main.go # gRPC 客戶端 └── go.mod
編寫 Protobuf 定義(proto/user.proto)
這是 gRPC 開發(fā)的核心,定義接口契約。
// 指定 Protobuf 版本
syntax = "proto3";
// 指定生成的 Go 代碼的包路徑
option go_package = "./proto";
// 定義包名
package user;
// 定義消息(數(shù)據(jù)結(jié)構(gòu))
message User {
uint32 id = 1; // 字段編號:1-15 占 1 字節(jié),常用字段優(yōu)先
string username = 2;
string email = 3;
}
message GetUserRequest {
uint32 user_id = 1;
}
message GetUserResponse {
User user = 1;
}
// 定義服務(wù)
service UserService {
// 一元 RPC 方法
rpc GetUser(GetUserRequest) returns (GetUserResponse);
}syntax = "proto3";:指定使用 Protobuf v3 版本(推薦,比 v2 更簡潔)。option go_package = "./proto";:指定生成的 Go 代碼的包路徑。- 消息字段編號:每個字段必須有唯一的編號,1-15 占 1 字節(jié),16-2047 占 2 字節(jié),常用字段建議用 1-15。
service Xxx { rpc Yyy(Req) returns (Resp) }:定義服務(wù),包含多個 RPC 方法。rpc 方法名(請求) returns (響應(yīng)):定義 RPC 方法。message Xxx { type field = tag; }:定義消息結(jié)構(gòu),tag 必須唯一
protoc --go_out=. --go-grpc_out=. proto/user.proto
執(zhí)行成功后,會在 proto/ 目錄下生成兩個文件:
user.pb.go:消息結(jié)構(gòu)的 Go 代碼user_grpc.pb.go:服務(wù)接口的 Go 代碼
服務(wù)端實現(xiàn)
import (pb "grpc-demo/proto")
// 定義服務(wù)結(jié)構(gòu)體,必須嵌入 Unimplemented*Server
type UserServer struct {
pb.UnimplementedUserServiceServer // 必須嵌入,保證向前兼容
}
// 實現(xiàn) Protobuf 中定義的 RPC 方法
func (s *UserServer) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) {
// 核心業(yè)務(wù)邏輯:查詢數(shù)據(jù)庫等
user := &pb.User{
Id: req.UserId,
Username: "zhangsan",
Email: "zhangsan@example.com",
}
return &pb.GetUserResponse{User: user}, nil
}
func main() {
// 監(jiān)聽端口
lis, _ := net.Listen("tcp", ":50051")
// 創(chuàng)建 gRPC 服務(wù)器
s := grpc.NewServer()
// 將服務(wù)實現(xiàn)注冊到 gRPC 服務(wù)器
pb.RegisterUserServiceServer(s, &UserServer{})
// 啟動服務(wù),監(jiān)聽 TCP 連接
s.Serve(lis)
}
type XxxServer struct { pb.UnimplementedXxxServer }:定義服務(wù)結(jié)構(gòu)體,必須嵌入 Unimplementedpb.UnimplementedUserServiceServer:必須嵌入這個結(jié)構(gòu)體,確保向前兼容,即使后續(xù)服務(wù)添加了新方法,舊的服務(wù)端代碼也不會報錯。- 實現(xiàn)服務(wù)接口:必須實現(xiàn)
.proto文件中定義的所有 RPC 方法。
客戶端實現(xiàn)
import (pb "grpc-demo/proto")
func main() {
// 連接服務(wù)端
conn, _ := grpc.Dial(
"localhost:50051",
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
defer conn.Close()
// 創(chuàng)建客戶端
client := pb.NewUserServiceClient(conn)
// 調(diào)用 RPC 方法
ctx := context.Background() // 空根上下文
resp, _ := client.GetUser(ctx, &pb.GetUserRequest{UserId: 1})
fmt.Printf("獲取用戶:%+v\n", resp.User)
}
client.Yyy(ctx, &Req{}):調(diào)用 RPC 方法
攔截器
攔截器類似 Gin 中間件,用于處理通用邏輯(日志、認(rèn)證、限流)。
// 日志攔截器
func LogInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
// 請求前邏輯
fmt.Printf("收到請求:%s\n", info.FullMethod)
// 調(diào)用實際 RPC 方法
resp, err := handler(ctx, req)
// 請求后邏輯
return resp, err
}
// 注冊攔截器
func main() {
lis, _ := net.Listen("tcp", ":50051")
// 創(chuàng)建服務(wù)器時注冊攔截器
s := grpc.NewServer(grpc.UnaryInterceptor(LogInterceptor))
pb.RegisterUserServiceServer(s, &UserServer{})
s.Serve(lis)
}
grpc.NewServer(grpc.UnaryInterceptor(...)):創(chuàng)建 gRPC 服務(wù)器并注冊攔截器
以上就是Go中跨語言實現(xiàn)傳輸?shù)姆椒ú襟E的詳細(xì)內(nèi)容,更多關(guān)于Go跨語言實現(xiàn)傳輸?shù)馁Y料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
golang 將[]byte轉(zhuǎn)成16進制的實現(xiàn)
這篇文章主要介紹了golang 將[]byte轉(zhuǎn)成16進制的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12
提升Golang應(yīng)用性能:深入理解Context的應(yīng)用
本文將深入探討如何通過深入理解和正確應(yīng)用Go語言中的Context來提升應(yīng)用性能。需要的朋友可以參考下2023-09-09
Go語言如何在Web服務(wù)中實現(xiàn)優(yōu)雅關(guān)機
在這篇文章中,我們將通過一個簡單的例子來演示如何在 Go 語言中使用 Gin 框架實現(xiàn)優(yōu)雅關(guān)機,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-11-11
golang簡易實現(xiàn)?k8s?的yaml上傳并應(yīng)用示例方案
這篇文章主要為大家介紹了golang簡易實現(xiàn)?k8s?的yaml上傳并應(yīng)用示例方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07

