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语言-为什么返回值为接口类型,却返回结构体
Apr 24 Golang
Golang 正则匹配效率详解
Apr 25 Golang
go web 预防跨站脚本的实现方式
Jun 11 Golang
使用GO语言实现Mysql数据库CURD的简单示例
Aug 07 Golang
victoriaMetrics库布隆过滤器初始化及使用详解
Apr 05 Golang
Golang数据类型和相互转换
Apr 12 Golang
golang连接MySQl使用sqlx库
Apr 14 Golang
golang定时器
Apr 14 Golang
GO语言异常处理分析 err接口及defer延迟
Apr 14 Golang
Go gRPC进阶教程gRPC转换HTTP
Jun 16 Golang
在ubuntu下安装go开发环境的全过程
Aug 05 Golang
Go语言编译原理之源码调试
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
一个简洁的多级别论坛
2006/10/09 PHP
再次研究下cache_lite
2007/02/14 PHP
两个开源的Php输出Excel文件类
2010/02/08 PHP
PHP下利用shell后台运行PHP脚本,并获取该脚本的Process ID的代码
2011/09/19 PHP
php 检查电子邮件函数(自写)
2014/01/16 PHP
30个php操作redis常用方法代码例子
2014/07/05 PHP
php防止sql注入之过滤分页参数实例
2014/11/03 PHP
PHP请求远程地址设置超时时间的解决方法
2016/10/29 PHP
php的RSA加密解密算法原理与用法分析
2020/01/23 PHP
JavaScript DOM学习第六章 表单实例
2010/02/19 Javascript
jQuery中$.fn的用法示例介绍
2013/11/05 Javascript
jquery检测input checked 控件是否被选中的方法
2014/03/26 Javascript
js实现选中页面文字将其分享到新浪微博
2015/11/05 Javascript
javascript中eval和with用法实例总结
2015/11/30 Javascript
微信小程序-图片、录音、音频播放、音乐播放、视频、文件代码实例
2016/11/22 Javascript
cnpm加速Angular项目创建的方法
2018/09/07 Javascript
使用js实现单链解决前端队列问题的方法
2020/02/03 Javascript
Vue+elementUI实现多图片上传与回显功能(含回显后继续上传或删除)
2020/03/23 Javascript
谈谈我在vue-cli3中用预渲染遇到的坑
2020/04/22 Javascript
Vue 中获取当前时间并实时刷新的实现代码
2020/05/12 Javascript
[38:41]2014 DOTA2国际邀请赛中国区预选赛 LGD VS CNB
2014/05/22 DOTA
Python中文竖排显示的方法
2015/07/28 Python
django站点管理详解
2017/12/12 Python
Python设置在shell脚本中自动补全功能的方法
2018/06/25 Python
详解python实现识别手写MNIST数字集的程序
2018/08/03 Python
python twilio模块实现发送手机短信功能
2019/08/02 Python
写一个方法1000的阶乘
2012/11/21 面试题
三八红旗集体先进事迹材料
2014/05/22 职场文书
党员教师四风自我剖析材料
2014/09/30 职场文书
收款授权委托书
2014/10/02 职场文书
一年级小学生评语大全
2014/12/25 职场文书
生产实习心得体会范文
2016/01/22 职场文书
2016年学校招生广告语
2016/01/28 职场文书
2019年大学生职业生涯规划书
2019/03/25 职场文书
python flask框架快速入门
2021/05/14 Python
vue3获取当前路由地址
2022/02/18 Vue.js