首頁 > 軟體

Go Grpc Gateway相容HTTP協定檔案自動生成閘道器

2022-06-16 14:01:51

前言

呼叫,讓使用者端可以更具自身情況自由選擇,伺服器端工作只需要做一份呢?還別說真還有一個準備好的輪子那就是今天的主角《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(還可以作為偵錯工具),何樂而不為呢?

以上就是Go Grpc Gateway相容HTTP協定檔案自動生成閘道器的詳細內容,更多關於Go Grpc Gateway相容HTTP的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com