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二维切片初始化的实现
Apr 08 Golang
为什么不建议在go项目中使用init()
Apr 12 Golang
golang中实现给gif、png、jpeg图片添加文字水印
Apr 26 Golang
golang http使用踩过的坑与填坑指南
Apr 27 Golang
golang goroutine顺序输出方式
Apr 29 Golang
Golang全局变量加锁的问题解决
May 08 Golang
golang三种设计模式之简单工厂、方法工厂和抽象工厂
Apr 10 Golang
Golang流模式之grpc的四种数据流
Apr 13 Golang
GoFrame基于性能测试得知grpool使用场景
Jun 21 Golang
Go语言编译原理之源码调试
Aug 05 Golang
基于Python实现西西成语接龙小助手
Aug 05 Golang
go goth封装第三方认证库示例详解
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
php下过滤html代码的函数 提高程序安全性
2010/03/02 PHP
供参考的 php 学习提高路线分享
2011/10/23 PHP
PHP 过滤页面中的BOM(实现代码)
2013/06/29 PHP
php实现的css文件背景图片下载器代码
2014/11/11 PHP
Yii实现多数据库主从读写分离的方法
2014/12/29 PHP
PHP中抽象类和抽象方法概念与用法分析
2016/05/24 PHP
thinkPHP的表达式查询用法详解
2016/09/14 PHP
弹出模态框modal的实现方法及实例
2017/09/19 PHP
Swoole4.4协程抢占式调度器详解
2019/05/23 PHP
js获取dom的高度和宽度(可见区域及部分等等)
2013/06/13 Javascript
javascript仿php的print_r函数输出json数据
2013/09/13 Javascript
jQuery实现动画效果的简单实例
2014/01/27 Javascript
javascript设计模式之工厂模式示例讲解
2014/03/04 Javascript
JS遍历Json字符串中键值对先转成JSON对象再遍历
2014/08/15 Javascript
JavaScript采用递归算法计算阶乘实例
2015/08/04 Javascript
JQuery中Ajax()的data参数类型实例分析
2015/12/15 Javascript
如何解决easyui自定义标签 datagrid edit combobox 手动输入保存不上
2015/12/26 Javascript
3kb jQuery代码搞定各种树形选择的实现方法
2016/06/10 Javascript
第一次接触神奇的Bootstrap表单
2016/07/27 Javascript
.net MVC+Bootstrap下使用localResizeIMG上传图片
2017/04/21 Javascript
Vue.js通用应用框架-Nuxt.js的上手教程
2017/12/25 Javascript
element-ui 远程搜索组件el-select在项目中组件化的实现代码
2019/12/04 Javascript
在Vue里如何把网页的数据导出到Excel的方法
2020/09/30 Javascript
11个Javascript小技巧帮你提升代码质量(小结)
2020/12/28 Javascript
Phantomjs抓取渲染JS后的网页(Python代码)
2016/05/13 Python
python使用requests模块实现爬取电影天堂最新电影信息
2019/04/03 Python
python中数组和矩阵乘法及使用总结(推荐)
2019/05/18 Python
Django 1.10以上版本 url 配置注意事项详解
2019/08/05 Python
Python 文件操作之读取文件(read),文件指针与写入文件(write),文件打开方式示例
2019/09/29 Python
Matlab中plot基本用法的具体使用
2020/07/17 Python
Python 使用SFTP和FTP实现对服务器的文件下载功能
2020/12/17 Python
详解如何用canvas画一个微笑的表情
2019/03/14 HTML / CSS
新西兰优惠网站:Treat Me
2019/07/04 全球购物
软件测试面试题
2015/10/21 面试题
分厂厂长岗位职责
2013/12/29 职场文书
《翻越远方的大山》教学反思
2014/04/13 职场文书