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 相关文章推荐
go:垃圾回收GC触发条件详解
Apr 24 Golang
go原生库的中bytes.Buffer用法
Apr 25 Golang
golang中实现给gif、png、jpeg图片添加文字水印
Apr 26 Golang
Go语言中的UTF-8实现
Apr 26 Golang
Go语言切片前或中间插入项与内置copy()函数详解
Apr 27 Golang
彻底理解golang中什么是nil
Apr 29 Golang
Go语言 go程释放操作(退出/销毁)
Apr 30 Golang
Go 在 MongoDB 中常用查询与修改的操作
May 07 Golang
Go语言基础map用法及示例详解
Nov 17 Golang
Golang日志包的使用
Apr 20 Golang
Go本地测试解耦任务拆解及沟通详解Go本地测试的思路沟通的重要性总结
Jun 21 Golang
Go gorilla securecookie库的安装使用详解
Aug 14 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
javascript数组与php数组的地址传递及值传递用法实例
2015/01/22 PHP
php日期操作技巧小结
2016/06/25 PHP
thinkphp ajaxfileupload实现异步上传图片的示例
2017/08/28 PHP
强悍无比的WEB开发好助手FireBug(Firefox Plugin)
2007/01/16 Javascript
jquery 学习之二 属性(类)
2010/11/25 Javascript
Js 弹出框口并返回值的两种常用方法
2010/12/30 Javascript
jQuery 中使用JSON的实现代码
2011/12/01 Javascript
5个最佳的Javascript日期处理类库分享
2012/04/15 Javascript
javascript 闭包详解
2015/07/02 Javascript
jquery实现横向图片轮播特效代码分享
2015/11/19 Javascript
jquery实现删除一个元素后面的所有元素功能
2015/12/21 Javascript
实例讲解jQuery中对事件的命名空间的运用
2016/05/24 Javascript
JQuery和HTML5 Canvas实现弹幕效果
2017/01/04 Javascript
jquery 校验中国身份证号码实例详解
2017/04/11 jQuery
vue3.0 CLI - 2.4 - 新组件 Forms.vue 中学习表单
2018/09/14 Javascript
vue中el-upload上传图片到七牛的示例代码
2018/10/19 Javascript
vue组件之间通信实例总结(点赞功能)
2018/12/05 Javascript
JavaScript键盘事件常见用法实例分析
2019/01/03 Javascript
Vue 使用计时器实现跑马灯效果的实例代码
2019/07/11 Javascript
[02:00]DAC2018主宣传片——龙征四海,剑问东方
2018/03/20 DOTA
[47:12]TFT vs Secret Supermajor小组赛C组 BO3 第三场 6.3
2018/06/04 DOTA
[01:28:44]DOTA2-DPC中国联赛定级赛 RNG vs iG BO3第一场 1月10日
2021/03/11 DOTA
简单介绍Python2.x版本中的cmp()方法的使用
2015/05/20 Python
详解Python设计模式编程中观察者模式与策略模式的运用
2016/03/02 Python
Python实现八大排序算法
2016/08/13 Python
Python中属性和描述符的正确使用
2016/08/23 Python
python密码错误三次锁定(实例讲解)
2017/11/14 Python
Scrapy框架CrawlSpiders的介绍以及使用详解
2017/11/29 Python
pandas 将索引值相加的方法
2018/11/15 Python
Python使用requests提交HTTP表单的方法
2018/12/26 Python
执行Django数据迁移时报 1091错误及解决方法
2019/10/14 Python
解决在keras中使用model.save()函数保存模型失败的问题
2020/05/21 Python
英语专业学生个人求职信
2014/01/28 职场文书
产品调价通知函
2015/04/20 职场文书
如何写好开幕词?
2019/06/24 职场文书
redis调用二维码时的不断刷新排查分析
2022/04/01 Redis