Go Grpc Gateway兼容HTTP協(xié)議文檔自動(dòng)生成網(wǎng)關(guān)
前言
調(diào)用,讓客戶端可以更具自身情況自由選擇,服務(wù)端工作只需要做一份呢?還別說(shuō)真還有一個(gè)準(zhǔn)備好的輪子那就是今天的主角《grpc-gateway》。
附上:
博文實(shí)例demo:https://github.com/sunmi-OS/grpc-gateway-demo
grpc-gateway官網(wǎng):https://github.com/grpc-ecosystem/grpc-gateway
一,grpc-gateway介紹
grpc-gateway是protoc的一個(gè)插件 。它讀取Grpc服務(wù)定義,并生成反向代理服務(wù)器,將RESTful JSON API請(qǐng)求轉(zhuǎn)換為Grpc的方式調(diào)用。主要是根據(jù) google.api.http定義中思想完成的,一下就是grpc-gateway結(jié)構(gòu)圖:

二,grpc-gateway環(huán)境準(zhǔn)備
grpc-gateway使用完全的Go語(yǔ)言進(jìn)行開(kāi)發(fā),所以安裝起來(lái)也非常簡(jiǎn)單,首先需要獲取相關(guān)的依賴包
PS:需要先準(zhǔn)備好準(zhǔn)備好protoc的環(huán)境
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結(jié)構(gòu)文件和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
最終可以看到以下文件

二,編寫(xiě)grpc-gateway服務(wù)
服務(wù)端代碼:
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服務(wù)已經(jīng)開(kāi)啟")
s.Serve(lis)
}運(yùn)行g(shù)rpc服務(wù)端:
go build grpc_service.go ./grpc_service

編寫(xiě)gateway服務(wù)
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("服務(wù)開(kāi)啟")
return http.ListenAndServe(":8080", mux)
}
func main() {
flag.Parse()
defer glog.Flush()
if err := run(); err != nil {
glog.Fatal(err)
}
}運(yùn)行網(wǎng)關(guān)程序
go build grpc_gateway.go ./grpc_gateway

使用http的方式調(diào)用網(wǎng)關(guān):
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

五,性能對(duì)比
對(duì)比以下兩項(xiàng):
http -> go -> grpc -> go
http -> go -> http -> grpc_gateway -> grpc -> go
全程使用ab 帶 -k進(jìn)行壓測(cè)
http -> go -> grpc -> go


http -> go -> http -> grpc_gateway -> grpc -> go


六,總結(jié)
在GO的場(chǎng)景下基本上4倍差距,但是考慮到本身Go在grpc和http上本身就有3.5倍的差距,本身在同等HTTP的情況下經(jīng)過(guò)grpc-gateway和不經(jīng)過(guò)直接到API差距大概在20~30%左右,這樣的性能消耗帶來(lái)的是兼容HTTP并且還可以自動(dòng)生成swagger(還可以作為調(diào)試工具),何樂(lè)而不為呢?
以上就是Go Grpc Gateway兼容HTTP協(xié)議文檔自動(dòng)生成網(wǎng)關(guān)的詳細(xì)內(nèi)容,更多關(guān)于Go Grpc Gateway兼容HTTP的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- golang通用的grpc?http基礎(chǔ)開(kāi)發(fā)框架使用快速入門
- Go創(chuàng)建Grpc鏈接池實(shí)現(xiàn)過(guò)程詳解
- go?doudou開(kāi)發(fā)gRPC服務(wù)快速上手實(shí)現(xiàn)詳解
- Golang?gRPC?HTTP協(xié)議轉(zhuǎn)換示例
- Go?gRPC進(jìn)階教程gRPC轉(zhuǎn)換HTTP
- Go?gRPC服務(wù)proto數(shù)據(jù)驗(yàn)證進(jìn)階教程
- Go?gRPC服務(wù)進(jìn)階middleware使用教程
- Go?gRPC進(jìn)階教程服務(wù)超時(shí)設(shè)置
- Go語(yǔ)言與gRPC的完美結(jié)合實(shí)戰(zhàn)演練
相關(guān)文章
Go語(yǔ)言實(shí)現(xiàn)類似c++中的多態(tài)功能實(shí)例
Go本身不具有多態(tài)的特性,不能夠像Java、C++那樣編寫(xiě)多態(tài)類、多態(tài)方法。但是,使用Go可以編寫(xiě)具有多態(tài)功能的類綁定的方法。下面來(lái)一起看看吧2016-09-09
Go語(yǔ)言使用Redis和Etcd實(shí)現(xiàn)高性能分布式鎖
這篇文章主要為大家介紹了Go語(yǔ)言使用Redis實(shí)現(xiàn)高性能分布式鎖示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
Golang使用gob實(shí)現(xiàn)結(jié)構(gòu)體的序列化過(guò)程詳解
Golang struct類型數(shù)據(jù)序列化用于網(wǎng)絡(luò)傳輸數(shù)據(jù)或在磁盤(pán)上寫(xiě)入數(shù)據(jù)。在分布式系統(tǒng)中,一端生成數(shù)據(jù)、然后序列化、壓縮和發(fā)送;在另一端,接收數(shù)據(jù)、然后解壓縮、反序列化和處理數(shù)據(jù),整個(gè)過(guò)程必須快速有效2023-03-03
大多數(shù)Go程序員都走過(guò)的坑盤(pán)點(diǎn)解析
這篇文章主要為大家介紹了大多數(shù)Go程序員都走過(guò)的坑盤(pán)點(diǎn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
淺析Go中函數(shù)的健壯性,panic異常處理和defer機(jī)制
這篇文章主要為大家詳細(xì)介紹了Go中函數(shù)的健壯性,panic異常處理和defer機(jī)制的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-10-10
Go中的fuzz模糊測(cè)試使用實(shí)戰(zhàn)詳解
這篇文章主要為大家介紹了Go中的fuzz模糊測(cè)試使用實(shí)戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12

