关于golang:gRPCGo入门教程

58次阅读

共计 4398 个字符,预计需要花费 11 分钟才能阅读完成。

protobuf 简介

Protocol Buffers(protobuf):与编程语言无关,与程序运行平台无关的 数据序列化协定 以及 接口定义语言(IDL: interface definition language)。

要应用 protobuf 须要先了解几个概念:

  • protobuf编译器 protoc,用于编译.proto 文件

    • 开源地址:https://github.com/protocolbu…
  • 编程语言的 protobuf 插件,搭配 protoc 编译器,依据 .proto 文件生成对应编程语言的代码。
  • protobuf runtime library:每个编程语言有各自的 protobuf runtime,用于实现各自语言的protobuf 协定。
  • Go 语言的 protobuf 插件和 runtime library 有过 2 个版本:

    • 第 1 个版本开源地址:https://github.com/golang/protobuf,蕴含有插件 proto-gen-go,能够生成xx.pb.goxx_grpc.pb.go。Go 工程里导入该版本的 protobuf runtime 的形式如下:

      import "github.com/golang/protobuf"
    • 第 2 个版本开源地址:https://github.com/protocolbuffers/protobuf-go,同样蕴含有插件 proto-gen-go。不过该项目标proto-gen-gov1.20版本开始,不再反对生成 gRPC 服务定义,也就是 xx_grpc.pb.go 文件。要生成 gRPC 服务定义须要应用 grpc-go 里的 progo-gen-go-grpc 插件。Go 工程里导入该版本的 protobuf runtime 的形式如下:

      import "google.golang.org/protobuf"

    举荐应用第 2 个版本,对 protobuf 的 API 做了优化和精简,并且把工程界线分分明了:

    • 第一,把 protobuf 的 Go 实现都放在 protobuf 的我的项目里,而不是放在 golang 语言我的项目上面。
    • 第二,把 gRPC 的生成,放在 grpc-go 我的项目里,而不是和 protobuf runtime 混在一起。

    有的老我的项目可能应用了第 1 个版本的 protobuf runtime,在老我的项目里开发新性能的时候也能够应用第 2 个版本protobuf runtime,反对 2 个版本在一个 Go 我的项目里共存。然而要 留神:一个我的项目里同时应用 2 个版本必须保障第一个版本的版本号不低于v1.4

gRPC-Go 简介

gRPC-Go: gRPC 的 Go 语言实现,基于 HTTP/ 2 的 RPC 框架。

开源地址:https://github.com/grpc/grpc-go

Go 我的项目里导入该模块的形式如下:

import "google.golang.org/grpc"

grpc-go我的项目里还蕴含有 protoc-gen-go-grpc 插件,用于依据 .proto 文件生成 xx_grpc.pb.go 文件。

环境装置

分为 3 步:

  • 装置 Go

    • 步骤参考:https://go.dev/doc/install
  • 装置 Protobuf 编译器protoc: 用于编译.proto 文件

    • 步骤参考:https://grpc.io/docs/protoc-i…
    • 执行如下命令查看 protoc 的版本号,确认版本号是 3 +,用于反对 protoc3

      protoc --version
  • 装置 protoc 编译器的 Go 语言插件

    • protoc-gen-go插件:用于生成 xx.pb.go 文件

      go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    • protoc-gen-go-grpc插件:用于生成 xx_grpc.pb.go 文件

      go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

留神:有的教程可能只让你装置protoc-gen-go,没有装置protoc-gen-go-grpc,那有 2 种状况:

  • 应用的是第 1 个版本 github.com/golang/protobufprotoc-gen-go插件。
  • 应用的是第 2 个版本 google.golang.org/protobufprotoc-gen-go插件并且 protoc-gen-go 版本号低于 v1.20。从v1.20 开始,第 2 个版本的 protoc-gen-go 插件不再反对生成 gRPC 服务定义。上面是官网阐明:

The v1.20 protoc-gen-go does not support generating gRPC service definitions. In the future, gRPC service generation will be supported by a new protoc-gen-go-grpc plugin provided by the Go gRPC project.

The github.com/golang/protobuf version of protoc-gen-go continues to support gRPC and will continue to do so for the foreseeable future.

官网示例

下载代码

grpc-go 的 v1.41.0 版本为例,下载代码并进入到 grpc-go/examples/helloworld 目录:

git clone -b v1.41.0 https://github.com/grpc/grpc-go
cd grpc-go/examples/helloworld

运行代码

  • 启动服务端

    go run greeter_server/main.go

    终端会打印如下内容,示意服务端曾经启动并且在监听 50051 端口

    2022/01/02 13:01:08 server listening at [::]:50051
  • 启动客户端。客户端会发送 SayHello 申请给服务端

    go run greeter_client/main.go

    终端会打印如下内容,示意收到了服务端的响应。

    2022/01/02 13:01:25 Greeting: Hello world

工程开发

本人在应用 protobufgrpc-go开发的时候,依照如下步骤来操作:

  • 定义 .proto 文件,包含音讯体和 rpc 服务接口定义
  • 应用 protoc 命令来编译 .proto 文件,用于生成 xx.pb.goxx_grpc.pb.go文件
  • 在服务端实现 rpc 里定义的办法
  • 客户端调用 rpc 办法,获取响应后果

咱们通过对下面的 grpc-go/examples/helloworld 做批改,来阐明上述步骤。

  • 第一步,在 helloworld.proto 里减少一个 rpc 办法 SayHelloAgain,参数和返回值和SayHello 放弃一样。

    // The greeting service definition.
    service Greeter {
      // Sends a greeting
      rpc SayHello (HelloRequest) returns (HelloReply) {}
      // send another greeting
      rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}}
  • 第二步,在 grpc-go/examples/helloworld 目录应用 protoc 命令编译 .proto 文件,生成新的 helloworld.pb.gohelloword_grpc.pb.go文件。命令如下:

    protoc --go_out=. --go_opt=paths=source_relative \
        --go-grpc_out=. --go-grpc_opt=paths=source_relative \
        helloworld/helloworld.proto
  • 第三步,在服务端实现 rpc 里新定义的办法 SayHelloAgain。在greeter_server/main.go 增加如下代码:

    func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {log.Printf("Received: %v", in.GetName())
        return &pb.HelloReply{Message: "Hello again" + in.GetName()}, nil
    }
  • 第四步,在客户端调用新定义的 rpc 办法,获取响应后果。在 greeter_client/main.go 增加如下代码:

    r2, err2 := c.SayHelloAgain(ctx, &pb.HelloRequest{Name: name})
    if err2 != nil {log.Fatalf("could not greet: %v", err2)
    }
    log.Printf("Greeting: %s", r2.GetMessage())
  • 第五步,运行程序

    • 先启动服务端

      go run greeter_server/main.go
    • 再启动客户端

      go run greeter_client/main.go Alice

客户端会打印如下内容:

2022/01/02 13:37:58 Greeting: Hello alice
2022/01/02 13:37:58 Greeting: Hello again alice

至此,咱们就对如何在 Go 工程里应用 protobufgRPC有了一个初步的理解和入门。

进阶学习

想要进一步学习,次要是深刻理解 protobufgRPC在 Go 语言里的应用技巧和原理

  • protobuf官网学习地址:

    • https://developers.google.com…
    • https://developers.google.com…
    • https://developers.google.com…
    • https://developers.google.com…
  • gRPC官网学习地址:

    • https://grpc.io/docs/language…

开源地址

文章和示例代码开源地址在 GitHub: https://github.com/jincheng9/go-tutorial

公众号:coding 进阶

集体网站:https://jincheng9.github.io/

知乎:https://www.zhihu.com/people/thucuhkwuji

References

  • https://grpc.io/docs/language…
  • https://github.com/protocolbu…
  • https://stackoverflow.com/que…
  • https://github.com/golang/pro…
  • https://github.com/protocolbu…

正文完
 0