Grpc-Gateway - Grpc兼容HTTP協議文檔自動生成網關

因為之前的測試結果讓筆者對PHP使用GRPC很失望友瘤,如果使用HTTP的方式Guzzle還可以提供并發(fā)能力來降低接口消耗扮饶,Grpc只能阻塞,但是如果使用HTTP的話對于調用限制和GO調用GO來說不太友好频敛,有沒有一個兩全其美的方式可以使用Grpc的前提下又兼容HTTP調用冈钦,讓客戶端可以更具自身情況自由選擇专挪,服務端工作只需要做一份呢授霸?還別說真還有一個準備好的輪子那就是今天的主角《grpc-gateway》裂允。

附上:

喵了個咪的博客:w-blog.cn

博文實例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環(huán)境準備

grpc-gateway使用完全的Go語言進行開發(fā)漂洋,所以安裝起來也非常簡單,首先需要獲取相關的依賴包

PS:需要先準備好準備好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結構文件和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(還可以作為調試工具)庭猩,何樂而不為呢?

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末陈症,一起剝皮案震驚了整個濱河市蔼水,隨后出現的幾起案子,更是在濱河造成了極大的恐慌爬凑,老刑警劉巖徙缴,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡于样,警方通過查閱死者的電腦和手機疏叨,發(fā)現死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來穿剖,“玉大人蚤蔓,你說我怎么就攤上這事『啵” “怎么了秀又?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長贬芥。 經常有香客問我吐辙,道長,這世上最難降的妖魔是什么蘸劈? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任昏苏,我火速辦了婚禮,結果婚禮上威沫,老公的妹妹穿的比我還像新娘贤惯。我一直安慰自己,他們只是感情好棒掠,可當我...
    茶點故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布孵构。 她就那樣靜靜地躺著,像睡著了一般烟很。 火紅的嫁衣襯著肌膚如雪颈墅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天雾袱,我揣著相機與錄音精盅,去河邊找鬼。 笑死谜酒,一個胖子當著我的面吹牛,可吹牛的內容都是我干的妻枕。 我是一名探鬼主播僻族,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼屡谐!你這毒婦竟也來了述么?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤愕掏,失蹤者是張志新(化名)和其女友劉穎度秘,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡剑梳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年唆貌,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片垢乙。...
    茶點故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡锨咙,死狀恐怖,靈堂內的尸體忽然破棺而出追逮,到底是詐尸還是另有隱情酪刀,我是刑警寧澤,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布钮孵,位于F島的核電站骂倘,受9級特大地震影響,放射性物質發(fā)生泄漏巴席。R本人自食惡果不足惜历涝,卻給世界環(huán)境...
    茶點故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望情妖。 院中可真熱鬧睬关,春花似錦、人聲如沸毡证。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽料睛。三九已至丐箩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間恤煞,已是汗流浹背屎勘。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留居扒,地道東北人概漱。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像喜喂,于是被迫代替她去往敵國和親瓤摧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,666評論 2 350

推薦閱讀更多精彩內容

  • 原文出處:gRPC gRPC分享 概述 gRPC 一開始由 google 開發(fā)玉吁,是一款語言中立照弥、平臺中立、開源的遠...
    小波同學閱讀 7,208評論 0 18
  • gRPC 是一個高性能进副、通用的開源RPC框架这揣,基于HTTP/2協議標準和Protobuf序列化協議開發(fā),支持眾多的...
    小波同學閱讀 19,476評論 6 19
  • 1.簡介 在gRPC中,客戶端應用程序可以直接調用不同計算機上的服務器應用程序上的方法给赞,就像它是本地對象一樣机打,使您...
    第八共同體閱讀 1,870評論 0 6
  • 寫在前面 首先聲明這篇文章只是介紹gRPC在Go語言中的使用入門級的文章,不包含多少深入的內容塞俱,讀者對象是g...
    foundwei閱讀 2,622評論 0 5
  • 一.什么是GRPC?作用是什么?優(yōu)點在哪里? 定義:(Google Remote Procedure Call P...
    RunningMan_Fly閱讀 9,450評論 13 10