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中semaphore(信号量)源码
Apr 03 Golang
go语言map与string的相互转换的实现
Apr 07 Golang
golang interface判断为空nil的实现代码
Apr 24 Golang
golang正则之命名分组方式
Apr 25 Golang
go 原生http web 服务跨域restful api的写法介绍
Apr 27 Golang
解决Golang time.Parse和time.Format的时区问题
Apr 29 Golang
Golang 如何实现函数的任意类型传参
Apr 29 Golang
golang 定时任务方面time.Sleep和time.Tick的优劣对比分析
May 05 Golang
Go语言并发编程 sync.Once
Oct 16 Golang
Go语言特点及基本数据类型使用详解
Mar 21 Golang
Go Grpc Gateway兼容HTTP协议文档自动生成网关
Jun 16 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 Transfer Code
2006/10/09 PHP
PHP array操作10个小技巧分享
2011/06/23 PHP
PHP反射类ReflectionClass和ReflectionObject的使用方法
2013/11/13 PHP
php实现获取文章内容第一张图片的方法
2014/11/04 PHP
php强制更新图片缓存的方法
2015/02/11 PHP
windows server 2008/2012安装php iis7 mysql环境搭建教程
2016/06/30 PHP
PHP实现在数据库百万条数据中随机获取20条记录的方法
2017/04/19 PHP
PHP编程实现csv文件导入mysql数据库的方法
2017/04/29 PHP
php layui实现前端多图上传实例
2019/07/30 PHP
一段非常简单的让图片自动切换js代码
2006/11/10 Javascript
通过 Dom 方法提高 innerHTML 性能
2008/03/26 Javascript
对象特征检测法判断浏览器对javascript对象的支持
2009/07/25 Javascript
详解AngularJS控制器的使用
2016/03/09 Javascript
AngularJS ng-repeat数组有重复值的解决方法
2016/10/23 Javascript
jQuery实现两列等高并自适应高度
2016/12/22 Javascript
JQuery异步提交表单与文件上传功能示例
2017/01/12 Javascript
node.js连接MongoDB数据库的2种方法教程
2017/05/17 Javascript
express框架实现基于Websocket建立的简易聊天室
2017/08/10 Javascript
React Native验证码倒计时工具类分享
2017/10/24 Javascript
JS中精巧的自动柯里化实现方法
2017/12/12 Javascript
bootstrap table列和表头对不齐的解决方法
2019/07/19 Javascript
vue使用axios实现excel文件下载的功能
2020/07/16 Javascript
[01:18:35]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS BO3 第一场 1月29日
2021/03/11 DOTA
详解django中使用定时任务的方法
2018/09/27 Python
djang常用查询SQL语句的使用代码
2019/02/15 Python
Python时间序列处理之ARIMA模型的使用讲解
2019/04/02 Python
HTML5拖拉上传文件的简单实例
2017/01/11 HTML / CSS
html2canvas生成的图片偏移不完整的解决方法
2020/05/19 HTML / CSS
Keds加拿大官网:购买帆布运动鞋和皮鞋
2019/09/26 全球购物
俄罗斯香水和化妆品在线商店:Aroma-butik
2020/02/28 全球购物
如何写一份好的自荐信
2014/01/02 职场文书
数学系个人求职信范文
2014/01/30 职场文书
大型主题婚礼活动策划方案
2014/09/15 职场文书
承诺函范文
2015/01/21 职场文书
晚会闭幕词
2015/01/28 职场文书
ConditionalOnProperty配置swagger不生效问题及解决
2022/06/14 Java/Android