Go语言实现开发一个简单的gRPC Demo

 更新时间:2023年07月16日 11:08:02   作者:不背锅运维  
这篇文章主要为大家详细介绍了如何利用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的资料请关注脚本之家其它相关文章!

相关文章

  • Go语言单向通道的实现

    Go语言单向通道的实现

    本文主要介绍了Go语言单向通道的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • golang 日志log与logrus示例详解

    golang 日志log与logrus示例详解

    log是Go语言标准库中一个简单的日志库,本文给大家介绍golang 日志log与logrus示例详解,感兴趣的朋友一起看看吧
    2025-03-03
  • Golang Map类型的使用(增删查改)

    Golang Map类型的使用(增删查改)

    在Go中,map是哈希表的引用,是一种key-value数据结构,本文主要介绍了Golang Map类型的使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-05-05
  • 在 Golang 中使用 Cobra 创建 CLI 应用

    在 Golang 中使用 Cobra 创建 CLI 应用

    这篇文章主要介绍了在 Golang 中使用 Cobra 创建 CLI 应用,来看下 Cobra 的使用,这里我们使用的 go1.13.3 版本,使用 Go Modules 来进行包管理,需要的朋友可以参考下
    2022-01-01
  • Win10系统下Golang环境搭建全过程

    Win10系统下Golang环境搭建全过程

    在编程语言的选取上,越来越多的人选择了Golang,下面这篇文章主要给大家介绍了关于Win10系统下Golang环境搭建的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • Go语言的Channel遍历方法详解

    Go语言的Channel遍历方法详解

    这篇文章主要介绍了Go语言的Channel遍历方法详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • Go语言struct要使用 tags的原因解析

    Go语言struct要使用 tags的原因解析

    这篇文章主要介绍了为什么 Go 语言 struct 要使用 tags,在本文中,我们将探讨为什么 Go 语言中需要使用 struct tags,以及 struct tags 的使用场景和优势,需要的朋友可以参考下
    2023-03-03
  • Golang中Error的设计与实践详解

    Golang中Error的设计与实践详解

    这篇文章主要为大家详细介绍了Golang中Error的设计以及是具体如何处理错误的相关知识,文中的示例代码简洁易懂,需要的小伙伴可以跟随小编一起学习一下
    2023-08-08
  • 深入解析golang中的标准库flag

    深入解析golang中的标准库flag

    Go语言内置的flag包实现了命令行参数的解析,flag包使得开发命令行工具更为简单,下面通过本文给大家详细介绍下golang中的标准库flag相关知识,感兴趣的朋友一起看看吧
    2021-11-11
  • 一文带你深入探索Golang操作mongodb的方法

    一文带你深入探索Golang操作mongodb的方法

    这篇文章主要为大家详细介绍了Golang操作mongodb的相关知识,包括:初始化项目工程、容器方式安装mongo和调试运行和编译运行,感兴趣的小伙伴可以了解一下
    2023-02-02

最新评论