Go Grpc Gateway兼容HTTP协议文档自动生成网关


Posted in Golang onJune 16, 2022

前言

调用,让客户端可以更具自身情况自由选择,服务端工作只需要做一份呢?还别说真还有一个准备好的轮子那就是今天的主角《grpc-gateway》。

附上:

博文实例demo:https://github.com/sunmi-OS/grpc-gateway-demo

grpc-gateway官网:https://github.com/grpc-ecosystem/grpc-gateway

一,grpc-gateway介绍

grpc-gateway是protoc的一个插件 。它读取Grpc服务定义,并生成反向代理服务器,将RESTful JSON API请求转换为Grpc的方式调用。主要是根据 google.api.http定义中思想完成的,一下就是grpc-gateway结构图:

Go Grpc Gateway兼容HTTP协议文档自动生成网关

二,grpc-gateway环境准备

grpc-gateway使用完全的Go语言进行开发,所以安装起来也非常简单,首先需要获取相关的依赖包

PS:需要先准备好准备好protoc的环境

go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
go get -u github.com/golang/protobuf/protoc-gen-go
cd $GOPATH/src/
mkdir -p grpc-gateway-demo/gateway
cd grpc-gateway-demo/gateway
vim gateway.proto
syntax = "proto3";
package gateway;
# 新增以下引入
import "google/api/annotations.proto";
message StringMessage {
    string value = 1;
}
# 修改方法增加http定义
# service Gateway {
#   rpc SayHello Echo(StringMessage) returns (StringMessage) {}
# }
service Gateway {
   rpc Echo(StringMessage) returns (StringMessage) {
       option (google.api.http) = {
           post: "/v1/example/echo"
           body: "*"
       };
   }
}

生成grpc结构文件和gateway文件:

protoc --proto_path=../ -I/usr/local/include -I. -I$GOPATH/src -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --go_out=plugins=grpc:. gateway.proto

protoc --proto_path=../ -I/usr/local/include -I. -I$GOPATH/src -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --grpc-gateway_out=logtostderr=true:. gateway.proto

最终可以看到以下文件

Go Grpc Gateway兼容HTTP协议文档自动生成网关

二,编写grpc-gateway服务

服务端代码:

cd ..
vim grpc_service.go
package main
import (
    "log"
    "net"
    pb "grpc-gateway-demo/gateway"
    "google.golang.org/grpc"
    "golang.org/x/net/context"
)
const (
    PORT = ":9192"
)
type server struct {}
func (s *server) Echo(ctx context.Context, in *pb.StringMessage) (*pb.StringMessage, error) {
    log.Println("request: ", in.Value)
    return &pb.StringMessage{Value: "Hello " + in.Value}, nil
}
func main() {
    lis, err := net.Listen("tcp", PORT)
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterGatewayServer(s, &server{})
    log.Println("rpc服务已经开启")
    s.Serve(lis)
}

运行grpc服务端:

go build grpc_service.go
./grpc_service

Go Grpc Gateway兼容HTTP协议文档自动生成网关

编写gateway服务

vim grpc_gateway.go
package main
import (
    "flag"
    "net/http"
    "log"
    "github.com/golang/glog"
    "golang.org/x/net/context"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "google.golang.org/grpc"
    gw "grpc-gateway-demo/gateway"
)
var (
    echoEndpoint = flag.String("echo_endpoint", "localhost:9192", "endpoint of Gateway")
)
func run() error {
    ctx := context.Background()
    ctx, cancel := context.WithCancel(ctx)
    defer cancel()
    mux := runtime.NewServeMux()
    opts := []grpc.DialOption{grpc.WithInsecure()}
    err := gw.RegisterGatewayHandlerFromEndpoint(ctx, mux, *echoEndpoint, opts)
    if err != nil {
        return err
    }
    log.Println("服务开启")
    return http.ListenAndServe(":8080", mux)
}
func main() {
    flag.Parse()
    defer glog.Flush()
    if err := run(); err != nil {
        glog.Fatal(err)
    }
}

运行网关程序

go build grpc_gateway.go
./grpc_gateway

Go Grpc Gateway兼容HTTP协议文档自动生成网关

使用http的方式调用网关:

curl -X POST -k http://localhost:8080/v1/example/echo -d '{"value":" world"}'
{"value":"Hello  world"}

四,使用gateway生成swagger文档

cd gateway
protoc -I/usr/local/include -I. \
  -I$GOPATH/src \
  -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
  --swagger_out=logtostderr=true:. \
  gateway.proto

Go Grpc Gateway兼容HTTP协议文档自动生成网关

五,性能对比

对比以下两项:

http -> go -> grpc -> go

http -> go -> http -> grpc_gateway -> grpc -> go

全程使用ab 带 -k进行压测

http -> go -> grpc -> go

Go Grpc Gateway兼容HTTP协议文档自动生成网关

Go Grpc Gateway兼容HTTP协议文档自动生成网关

http -> go -> http -> grpc_gateway -> grpc -> go

Go Grpc Gateway兼容HTTP协议文档自动生成网关

Go Grpc Gateway兼容HTTP协议文档自动生成网关

六,总结

在GO的场景下基本上4倍差距,但是考虑到本身Go在grpc和http上本身就有3.5倍的差距,本身在同等HTTP的情况下经过grpc-gateway和不经过直接到API差距大概在20~30%左右,这样的性能消耗带来的是兼容HTTP并且还可以自动生成swagger(还可以作为调试工具),何乐而不为呢?

以上就是Go Grpc Gateway兼容HTTP协议文档自动生成网关的详细内容,更多关于Go Grpc Gateway兼容HTTP的资料请关注三水点靠木其它相关文章!


Tags in this post...

Golang 相关文章推荐
golang在GRPC中设置client的超时时间
Apr 27 Golang
解决goland 导入项目后import里的包报红问题
May 06 Golang
使用golang编写一个并发工作队列
May 08 Golang
Go遍历struct,map,slice的实现
Jun 13 Golang
golang 实用库gotable的具体使用
Jul 01 Golang
Go语言空白表示符_的实例用法
Jul 04 Golang
入门学习Go的基本语法
Jul 07 Golang
Go语言并发编程 sync.Once
Oct 16 Golang
golang定时器
Apr 14 Golang
Golang 字符串的常见操作
Apr 19 Golang
Golang实现可重入锁的示例代码
May 25 Golang
基于Python实现西西成语接龙小助手
Aug 05 Golang
Go gRPC进阶教程gRPC转换HTTP
Jun 16 #Golang
GoFrame gredis缓存DoVar Conn连接对象 自动序列化GoFrame gredisDo/DoVar方法Conn连接对象自动序列化/反序列化总结
Jun 14 #Golang
Go调用Rust方法及外部函数接口前置
详解Go语言中配置文件使用与日志配置
Jun 01 #Golang
详解Go语言中Get/Post请求测试
Golang实现可重入锁的示例代码
May 25 #Golang
Go web入门Go pongo2模板引擎
May 20 #Golang
You might like
老版本PHP转义Json里的特殊字符的函数
2015/06/08 PHP
thinkphp jquery实现图片上传和预览效果
2020/07/22 PHP
php文件操作之文件写入字符串、数组的方法分析
2019/04/15 PHP
laravel 查询数据库获取结果实现判断是否为空
2019/10/24 PHP
Jquery 实现Tab效果 思路是js思路
2010/03/02 Javascript
js 控制下拉菜单刷新的方法
2013/03/03 Javascript
JavaScript加强之自定义event事件
2013/09/21 Javascript
nodejs实现bigpipe异步加载页面方案
2016/01/26 NodeJs
利用jQuery实现CheckBox全选/全不选/反选的简单代码
2016/05/31 Javascript
基于vue2.0+vuex的日期选择组件功能实现
2017/03/13 Javascript
详解Vue-基本标签和自定义控件
2017/03/24 Javascript
详解angular 中的自定义指令之详解API
2017/06/20 Javascript
jQuery实现节点的追加、替换、删除、复制功能示例
2017/07/11 jQuery
jQuery.Ajax()的data参数类型详解
2017/07/23 jQuery
基于vue 实现token验证的实例代码
2017/12/14 Javascript
基于three.js编写的一个项目类示例代码
2018/01/05 Javascript
详解react内联样式使用webpack将px转rem
2018/09/13 Javascript
代码分析vue中如何配置less
2018/09/28 Javascript
layui实现tab的添加拒绝重复的方法
2019/09/04 Javascript
JavaScript中的null和undefined用法解析
2019/09/30 Javascript
[33:09]完美世界DOTA2联赛循环赛 Forest vs DM BO2第二场 10.29
2020/10/29 DOTA
[37:03]完美世界DOTA2联赛PWL S3 INK ICE vs GXR 第二场 12.16
2020/12/18 DOTA
Python备份目录及目录下的全部内容的实现方法
2016/06/12 Python
python中如何使用朴素贝叶斯算法
2017/04/06 Python
python 判断是否为正小数和正整数的实例
2017/07/23 Python
python多进程并行代码实例
2019/09/30 Python
Django自定义列表 models字段显示方式
2020/04/03 Python
HTML5地理定位_动力节点Java学院整理
2017/07/12 HTML / CSS
在网上学习全世界最好的课程:Coursera
2017/11/07 全球购物
Sunglasses Shop瑞典:欧洲领先的太阳镜网上商店
2018/04/22 全球购物
高二学生评语大全
2014/04/25 职场文书
法定代表人授权委托书范文
2014/08/02 职场文书
民间个人借款协议书
2014/09/30 职场文书
2014感恩节演讲稿大全
2014/10/11 职场文书
保管员岗位职责
2015/02/14 职场文书
5种方法告诉你如何使JavaScript 代码库更干净
2021/09/15 Javascript