Go語言實現(xiàn)開發(fā)一個簡單的gRPC Demo
Part1先決條件
獲得并安裝好Golang(https://go.dev/doc/install)
Protocol buffer compiler(protobuf編譯器), protoc version 3(protoc工具版本建議為3版本),獲得并安裝:https://github.com/protocolbuffers/protobuf/releases
安裝protocol編譯器的Go插件
go?install?google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 go?install?google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
Part2開發(fā)環(huán)境準(zhǔn)備
準(zhǔn)備go環(huán)境
wget?https://go.dev/dl/go1.20.5.linux-amd64.tar.gz tar?-zxf?go1.20.5.linux-amd64.tar.gz mv?go?/usr/local/
安裝protobuf編譯器protoc
wget?https://github.com/protocolbuffers/protobuf/releases/download/v23.4/protoc-23.4-linux-x86_64.zip mkdir?protoc-23.4 mv?protoc-23.4-linux-x86_64.zip cd?protoc-23.4 unzip?protoc-23.4-linux-x86_64.zip rm?-rf?protoc-23.4-linux-x86_64.zip cd?.. mv?protoc-23.4?/usr/local/
添加相關(guān)環(huán)境變量
export?GOROOT="/usr/local/go" export?GOPATH="/home/tantianran/goCode" export?GOPROXY="https://goproxy.cn,direct" export?GO111MODULE="on" export?PATH=$PATH:$GOROOT/bin:$GOPATH:$GOPATH/bin export?PROTOC_HOME=/usr/local/protoc-23.4 export?PATH=$PATH:$PROTOC_HOME/bin
Part3實戰(zhàn):開發(fā)一個簡單的gRPC Demo
1.創(chuàng)建user-service模塊
tantianran@go-dev:~/goCode/src$?mkdir?user-service tantianran@go-dev:~/goCode/src$?cd?user-service/ tantianran@go-dev:~/goCode/src/user-service$?go?mod?init
2.使用protobuf idl語言定義服務(wù)接口
創(chuàng)建service包
tantianran@go-dev:~/goCode/src/user-service$?mkdir?service tantianran@go-dev:~/goCode/src/user-service$?cd?service/
service/users.proto內(nèi)容:
syntax = "proto3"; option go_package = "user-service/service"; // 服務(wù)和方法 service Users { rpc GetUser (UserGetRequest) returns (UserGetReply) {} } // 請求消息 message UserGetRequest { string email = 1; int32 id = 2; } // 響應(yīng)消息 message User { string id = 1; string first_name = 2; string last_name = 3; int32 age = 4; } message UserGetReply { User user = 1; // 嵌套 }
3.生成客戶端和服務(wù)端代碼
首先安裝用于編譯器的go語言插件protoc-gen-go
go?install?google.golang.org/protobuf/cmd/protoc-gen-go@latest
開始生成
tantianran@go-dev:~/goCode/src/user-service/service$?protoc?--go_out=.?--go_opt=paths=source_relative?--go-grpc_out=.?--go-grpc_opt=paths=source_relative?users.proto tantianran@go-dev:~/goCode/src/user-service/service$?ls?-l total?24 -rw-rw-r--?1?tantianran?tantianran???37?Jul?11?10:05?go.mod -rw-rw-r--?1?tantianran?tantianran?3387?Jul?11?10:10?users_grpc.pb.go -rw-rw-r--?1?tantianran?tantianran?8984?Jul?11?10:10?users.pb.go -rw-rw-r--?1?tantianran?tantianran??362?Jul?11?10:09?users.proto
4.編寫服務(wù)器
創(chuàng)建server包
tantianran@go-dev:~/goCode/src$?cd?user-service/ tantianran@go-dev:~/goCode/src/user-service$?mkdir?server tantianran@go-dev:~/goCode/src/user-service$?cd?server/
server/server.go
package?main import?( ?"context" ?"log" ?"net" ?"os" ?users?"user-service/service"?//?導(dǎo)入之前生成的包 ?"google.golang.org/grpc" ) //?userService類型是Users服務(wù)的服務(wù)處理程序 type?userService?struct?{ ?users.UnimplementedUsersServer?//?這個字段對于gRPC中的任何服務(wù)實現(xiàn)都是強(qiáng)制性的 } func?(s?*userService)?GetUser(ctx?context.Context,?in?*users.UserGetRequest)?(*users.UserGetReply,?error)?{ ?//?打印客戶端傳過來的數(shù)據(jù) ?log.Printf("已接收到郵件地址:?%s,?還有ID:?%d",?in.Email,?in.Id) ?//?自定義數(shù)據(jù)響應(yīng)給客戶端 ?u?:=?users.User{ ??Id:????????"user-782935", ??FirstName:?"tan", ??LastName:??"tianran", ??Age:???????30, ?} ?return?&users.UserGetReply{User:?&u},?nil } //?向gRPC服務(wù)器注冊Users服務(wù) func?registerServices(s?*grpc.Server)?{ ?users.RegisterUsersServer(s,?&userService{}) } //?啟動gRPC服務(wù)器 func?startServer(s?*grpc.Server,?l?net.Listener)?error?{ ?return?s.Serve(l) } func?main()?{ ?listenAddr?:=?os.Getenv("LISTEN_ADDR") ?if?len(listenAddr)?==?0?{ ??listenAddr?=?":50051" ?} ?lis,?err?:=?net.Listen("tcp",?listenAddr) ?if?err?!=?nil?{ ??log.Fatal(err) ?} ?s?:=?grpc.NewServer() ?registerServices(s) ?log.Fatal(startServer(s,?lis)) }
5.編寫客戶端
tantianran@go-dev:~/goCode/src$?cd?user-service/ tantianran@go-dev:~/goCode/src/user-service$?mkdir?client/ tantianran@go-dev:~/goCode/src/user-service$?cd?client/
client/main.go
package?main import?( ?"context" ?"log" ?"os" ?users?"user-service/service"?//?導(dǎo)入之前生成的包 ?"google.golang.org/grpc" ) //?建立與服務(wù)器的連接(通道) func?setupGrpcConnection(addr?string)?(*grpc.ClientConn,?error)?{ ?return?grpc.DialContext( ??context.Background(), ??addr, ??grpc.WithInsecure(), ??grpc.WithBlock(), ?) } //?創(chuàng)建客戶端與Users服務(wù)通信 func?getUserServiceClient(conn?*grpc.ClientConn)?users.UsersClient?{ ?return?users.NewUsersClient(conn) } //?調(diào)用Users服務(wù)中的GetUser()方法 func?getUser(client?users.UsersClient,?u?*users.UserGetRequest)?(*users.UserGetReply,?error)?{ ?return?client.GetUser(context.Background(),?u) } func?main()?{ ?if?len(os.Args)?!=?2?{ ??log.Fatal("缺少gRPC服務(wù)器地址") ?} ?conn,?err?:=?setupGrpcConnection(os.Args[1]) ?if?err?!=?nil?{ ??log.Fatal(err) ?} ?defer?conn.Close() ?c?:=?getUserServiceClient(conn) ?result,?err?:=?getUser(c,?&users.UserGetRequest{ ??Email:?"tantianran@qq.com", ??Id:????801896, ?}) ?if?err?!=?nil?{ ??log.Fatal(err) ?} ?//?打印響應(yīng) ?log.Printf("收到響應(yīng):?%s?%s?%s?%d\n",?result.User.Id,?result.User.FirstName,?result.User.LastName,?result.User.Age) }
Part4驗證效果
服務(wù)器
tantianran@go-dev:~/goCode/src/user-service/server$ go run server.go
2023/07/12 00:59:01 已接收到郵件地址: tantianran@qq.com, 還有ID: 801896
客戶端
tantianran@go-dev:~/goCode/src/user-service/client$ go run main.go localhost:50051
2023/07/12 00:59:01 收到響應(yīng): user-782935 tan tianran 30
以上就是Go語言實現(xiàn)開發(fā)一個簡單的gRPC Demo的詳細(xì)內(nèi)容,更多關(guān)于Go gRPC的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
在?Golang?中使用?Cobra?創(chuàng)建?CLI?應(yīng)用
這篇文章主要介紹了在?Golang?中使用?Cobra?創(chuàng)建?CLI?應(yīng)用,來看下?Cobra?的使用,這里我們使用的?go1.13.3?版本,使用?Go?Modules?來進(jìn)行包管理,需要的朋友可以參考下2022-01-01Win10系統(tǒng)下Golang環(huán)境搭建全過程
在編程語言的選取上,越來越多的人選擇了Golang,下面這篇文章主要給大家介紹了關(guān)于Win10系統(tǒng)下Golang環(huán)境搭建的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01深入解析golang中的標(biāo)準(zhǔn)庫flag
Go語言內(nèi)置的flag包實現(xiàn)了命令行參數(shù)的解析,flag包使得開發(fā)命令行工具更為簡單,下面通過本文給大家詳細(xì)介紹下golang中的標(biāo)準(zhǔn)庫flag相關(guān)知識,感興趣的朋友一起看看吧2021-11-11