Go Grpc Gateway兼容HTTP协议文档自动生成网关
作者:文振熙 发布时间:2024-05-21 10:27:16
前言
调用,让客户端可以更具自身情况自由选择,服务端工作只需要做一份呢?还别说真还有一个准备好的轮子那就是今天的主角《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结构图:
二,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
最终可以看到以下文件
二,编写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
编写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
使用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
五,性能对比
对比以下两项:
http -> go -> grpc -> go
http -> go -> http -> grpc_gateway -> grpc -> go
全程使用ab 带 -k进行压测
http -> go -> grpc -> go
http -> go -> http -> grpc_gateway -> grpc -> go
六,总结
在GO的场景下基本上4倍差距,但是考虑到本身Go在grpc和http上本身就有3.5倍的差距,本身在同等HTTP的情况下经过grpc-gateway和不经过直接到API差距大概在20~30%左右,这样的性能消耗带来的是兼容HTTP并且还可以自动生成swagger(还可以作为调试工具),何乐而不为呢?
来源:https://juejin.cn/post/6844904074454925319


猜你喜欢
- 自己也百度了一下,然后写的,分为了三个部分,见三段代码代码:主程序代码import timefrom selenium&
- keras自定义函数时候,正常在模型里自己写好自定义的函数,然后在模型编译的那行代码里写上接口即可。如下所示,focal_loss和fbet
- 说完了理论,我们来做点实事。这篇文章将介绍使用 Javascript 实现的动画组件。下面记录下当时编写这个组件的考虑的些问题,对技术细节感
- 1、问题描述某厂生产甲乙两种饮料,每百箱甲饮料需用原料6千克、工人10名,获利10万元;每百箱乙饮料需用原料5千克、工人20名,获利9万元。
- 本文实例讲述了C#连接Oracle数据库的方法。分享给大家供大家参考。具体实现方法如下://1、添加引用 System.data.oracl
- 本文实例讲述了python使用htmllib分析网页内容的方法。分享给大家供大家参考。具体实现方法如下:import htmllib, ur
- 本文实例分析了python动态性强类型用法。分享给大家供大家参考。具体如下:Python变量声明和定义与C#不同,Python在使用变量之前
- 今日上课,有位同学问到:w和w+有何区别呢。说实话,我们经常只是用一种权限,没用在意之间的区别,实际上,w+具有可读可写权限,而w只有可写权
- 引言:Flask是Python社区非常流行的一个Web开发框架,本文将尝试将介绍APScheduler应用于Flask之中。1. Flask
- 1.在pycharm下安装scrapy函数库2.将安装好scrapy函数库下的路径配置到系统path的环境变量中3.打开cmd终端输入:sc
- 在ASP中加密方法有对应的解密方法好象不多,现在根据前辈资料整理出在asp中加密与解密函数,根据RSA 算法实现的。什么是RSA?
- SQLServer分页方式附带50万数据分页时间[本机访问|已重启SQL服务|无其他程序干扰][非索引排序]环境 WIN7 SQL服务12.
- 首先要注册一个账号密码,通过账号密码登录,并且滑块验证,自动输入搜索关键词,进行跳转翻页爬取数据,并保存到Excel文件中。代码运行时,滑块
- 前言在CSDN发的第一篇文章,时隔两年,终于实现了爬微博的自由!本文可以解决微博预登录、识别“展开全文”并爬取完整数据、翻页设置等问题。由于
- 百度指数抓取,再用图像识别得到指数前言:土福曾说,百度指数很难抓,在淘宝上面是20块1个关键字:哥那么叼的人怎么会被他吓到,于是乎花了零零碎
- view()函数是在torch.Tensor.view()下的一个函数,可以有tensor调用,也可以有variable调用。其作用在于返回
- 一、将数据写入opengauss前提准备:成功opengauss数据库,并创建用户jack,创建数据库datasets。数据准备:所用数据以
- 数据字典是Oracle存放有关数据库信息的地方,其用途是用来描述数据的。比如一个表的创建者信息,创建时间信息,所属表空间信息,用户访问权限信
- WGAN与GAN的不同去除sigmoid使用具有动量的优化方法,比如使用RMSProp要对Discriminator的权重做修整限制以确保l
- 本文实例讲述了jsp+ajax实现无刷新上传文件的方法。分享给大家供大家参考,具体如下:列表页:selectaddress.jspjs页:a