Go语言实现开发一个简单的gRPC Demo
作者:不背锅运维
这篇文章主要为大家详细介绍了如何利用Go语言实现开发一个简单的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开发环境准备
准备go环境
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/
添加相关环境变量
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实战:开发一个简单的gRPC Demo
1.创建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语言定义服务接口
创建service包
tantianran@go-dev:~/goCode/src/user-service$ mkdir service tantianran@go-dev:~/goCode/src/user-service$ cd service/
service/users.proto内容:
syntax = "proto3"; option go_package = "user-service/service"; // 服务和方法 service Users { rpc GetUser (UserGetRequest) returns (UserGetReply) {} } // 请求消息 message UserGetRequest { string email = 1; int32 id = 2; } // 响应消息 message User { string id = 1; string first_name = 2; string last_name = 3; int32 age = 4; } message UserGetReply { User user = 1; // 嵌套 }
3.生成客户端和服务端代码
首先安装用于编译器的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.编写服务器
创建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" // 导入之前生成的包 "google.golang.org/grpc" ) // userService类型是Users服务的服务处理程序 type userService struct { users.UnimplementedUsersServer // 这个字段对于gRPC中的任何服务实现都是强制性的 } func (s *userService) GetUser(ctx context.Context, in *users.UserGetRequest) (*users.UserGetReply, error) { // 打印客户端传过来的数据 log.Printf("已接收到邮件地址: %s, 还有ID: %d", in.Email, in.Id) // 自定义数据响应给客户端 u := users.User{ Id: "user-782935", FirstName: "tan", LastName: "tianran", Age: 30, } return &users.UserGetReply{User: &u}, nil } // 向gRPC服务器注册Users服务 func registerServices(s *grpc.Server) { users.RegisterUsersServer(s, &userService{}) } // 启动gRPC服务器 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" // 导入之前生成的包 "google.golang.org/grpc" ) // 建立与服务器的连接(通道) func setupGrpcConnection(addr string) (*grpc.ClientConn, error) { return grpc.DialContext( context.Background(), addr, grpc.WithInsecure(), grpc.WithBlock(), ) } // 创建客户端与Users服务通信 func getUserServiceClient(conn *grpc.ClientConn) users.UsersClient { return users.NewUsersClient(conn) } // 调用Users服务中的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服务器地址") } 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) } // 打印响应 log.Printf("收到响应: %s %s %s %d\n", result.User.Id, result.User.FirstName, result.User.LastName, result.User.Age) }
Part4验证效果
服务器
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 收到响应: user-782935 tan tianran 30
以上就是Go语言实现开发一个简单的gRPC Demo的详细内容,更多关于Go gRPC的资料请关注脚本之家其它相关文章!