写点什么

gRPC 学习之五:gRPC-Gateway 实战

作者:Java高工P7
  • 2021 年 11 月 11 日
  • 本文字数:2752 字

    阅读完需:约 9 分钟

  1. 极速搭建 gRPC-Gateway 环境;

  2. 编写 proto 文件;

  3. 根据 proto 文件生成 gRPC、gRPC-Gateway 源码;

  4. 添加业务代码;

  5. 编译、运行、验证;

提前说明文件和目录

  • 本次实战在 $GOPATH/src 目录下新增文件夹 helloworld,里面总共有以下内容:


[golang@centos7 src]$ tree helloworld/


helloworld/


├── gateway


│ └── helloworld.gw.go


├── helloworld.pb.go


├── helloworld.pb.gw.go


├── helloworld.proto


├── helloworld.swagger.json


└── server


└── server.go


  • 准备工作完成,接下来正式开始开发;

前提条件

  • 本文的所有操作都没有用到 root 账号,而是前文创建的 golang 账号;

  • 请参照以下两篇文章将 GO 环境和 gRPC 环境搭建好:


  1. 在CentOS7部署和设置GO

  2. GO的gRPC开发环境准备

极速搭建 gRPC-Gateway 环境

  • 所谓的搭建 gRPC-Gateway 环境,其实是完成以下三件事:



  1. 在搭建环境时参考了一些网上的文章,结果遇到了各种问题一直没有成功(我当然不会认为文章有问题,必须认识到是自己能力不足的原因所致);

  2. 经过反复折腾后终于成功后,我把所有操作做成一个 shell 脚本,执行以下命令即可完成上图中的所有操作:


curl -o install-grpc-gateway.sh \


https://raw.githubusercontent.com/zq2599/blog_demos/master/files/install-grpc-gateway.sh \


&& chmod a+x ./install-grpc-gateway.sh \


&& ./install-


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


grpc-gateway.sh


  1. 进入 $GOPATH/bin 目录,可见新增两个文件 protoc-gen-grpc-gateway 和 protoc-gen-swagger:


[golang@centos7 ~]GOPATH/bin


[golang@centos7 bin]$ ls -al


总用量 26708


drwxrwxr-x. 2 golang golang 98 12 月 19 08:59 .


drwxrwxr-x. 5 golang golang 39 12 月 19 08:21 ..


-rwxr-x---. 1 golang golang 5253272 12 月 19 08:20 protoc


-rwxrwxr-x. 1 golang golang 8461147 12 月 19 08:21 protoc-gen-go


-rwxrwxr-x. 1 golang golang 6717463 12 月 19 08:59 protoc-gen-grpc-gateway


-rwxrwxr-x. 1 golang golang 6908535 12 月 19 08:59 protoc-gen-swagger


  • 现在环境准备好了,开始开发;

编写 proto 文件

  • 在 $GOPATH/src 目录下,新建文件夹 helloworld,里面新建文件 helloworld.proto,内容如下,有几处要注意的地方稍后会说:


// 协议类型


syntax = "proto3";


// 包名


package helloworld;


import "google/api/annotations.proto";


// 定义的服务名


service Greeter {


// 具体的远程服务方法


rpc SayHello (HelloRequest) returns (HelloReply) {


option (google.api.http) = {


post: "/helloworld"


body: "*"


};


}


}


// SayHello 方法的入参,只有一个字符串字段


message HelloRequest {


string name = 1;


}


// SayHello 方法的返回值,只有一个字符串字段


message HelloReply {


string message = 1;


}


  • 上述 proto 文件有以下几处要注意的地方:


  1. 整个文件其实就是以 《初试GO版gRPC开发》一文中的 helloworld.proto 为基础,增加了两处内容;

  2. 增加的第一处,是用 import 关键词导入 google/api/annotations.proto;

  3. 增加的第二处,是 SayHello 方法的声明处,增加了 option 配置,作用是配置 SayHello 方法对外暴露的 RESTful 接口的信息;

  4. 在使用 protoc-gen-grpc-gateway 的时候,上述两处配置会被识别到并生成对应的代码;

根据 proto 文件生成 gRPC、gRPC-Gateway 源码

  1. proto 文件编写完成,接下来是生成 gRPC、gRPC-Gateway 的源码;

  2. 生成 gRPC 源码的命令咱们前面的文章中已经用过,如下:


protoc -I. \


-I$GOPATH/src \


-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \


--go_out=plugins=grpc:. \


helloworld.proto


  1. 执行完成后会在当前目录生成 helloworld.pb.go 文件;

  2. 执行生成 gRPC-Gateway 源码的命令:


protoc -I. \


-I$GOPATH/src \


-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \


--grpc-gateway_out=logtostderr=true:. \


helloworld.proto


  1. 执行完成后会在当前目录生成 helloworld.pb.gw.go 文件;

  2. 执行生成 swagger 文件的命令:


protoc -I. \


-I$GOPATH/src \


-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \


--swagger_out=logtostderr=true:. \


helloworld.proto


  1. 执行完成后会在当前目录生成 helloworld.swagger.json 文件;

  2. 至此,helloworld 目录下一共有这些内容:


[golang@centos7 src]$ tree helloworld/


helloworld/


├── helloworld.pb.go


├── helloworld.pb.gw.go


├── helloworld.proto


└── helloworld.swagger.json


0 directories, 4 files


  1. 接下来开始编码,把运行整个服务所需的代码补全;

  2. 由于篇幅限制,本文暂不提及 swagger 相关的开发和验证,因此生成的 helloworld.swagger.json 文件本篇用不上,留待下一篇文章使用;

编写服务端代码 server.go 并启动

  1. 接下来编写服务端代码 server.go,这个和《初试GO版gRPC开发》中的 server.go 内容一样;

  2. 在 $GOPATH/src/helloworld 目录下新建文件夹 server,在此文件夹下新建 server.go,内容如下,已经添加详细注释:


package main


import (


"context"


"log"


"net"


"google.golang.org/grpc"


pb "helloworld"


)


const (


port = ":50051"


)


// 定义结构体,在调用注册 api 的时候作为入参,


// 该结构体会带上 SayHello 方法,里面是业务代码


// 这样远程调用时就执行了业务代码了


type server struct {


// pb.go 中自动生成的,是个空结构体


pb.UnimplementedGreeterServer


}


// 业务代码在此写,客户端远程调用 SayHello 时,


// 会执行这里的代码


func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {


// 打印请求参数


log.Printf("Received: %v", in.GetName())


// 实例化结构体 HelloReply,作为返回值


return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil


}


func main() {


// 要监听的协议和端口


lis, err := net.Listen("tcp", port)


if err != nil {


log.Fatalf("failed to listen: %v", err)


}


// 实例化 gRPC server 结构体


s := grpc.NewServer()


// 服务注册


pb.RegisterGreeterServer(s, &server{})


log.Println("开始监听,等待远程调用...")


if err := s.Serve(lis); err != nil {


log.Fatalf("failed to serve: %v", err)


}


}


  1. 在 server.go 所在目录执行 go run server.go,控制台提示如下:


[golang@centos7 server]$ go run server.go


2020/12/13 08:20:32 开始监听,等待远程调用...


  1. 此时 gRPC 的服务端已启动,可以响应远程调用,接下来开发反向代理(Reverse Proxy);

编写反向代理(Reverse Proxy)代码 helloworld.gw.go 并启动

  • 接下来编反向代理(Reverse Proxy)代码 helloworld.gw.go;

  • 在 $GOPATH/src/helloworld 目录下新建文件夹 gateway,在此文件夹下新建 helloworld.gw.go,内容如下,有几处要注意的地方稍后会说明:


package main


import (

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
gRPC学习之五:gRPC-Gateway实战