Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > Go gRPC

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的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文