網(wǎng)站首頁 編程語言 正文
前言
調(diào)用,讓客戶端可以更具自身情況自由選擇,服務(wù)端工作只需要做一份呢?還別說真還有一個(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請求轉(zhuǎn)換為Grpc的方式調(diào)用。主要是根據(jù) google.api.http定義中思想完成的,一下就是grpc-gateway結(jié)構(gòu)圖:
二,grpc-gateway環(huán)境準(zhǔn)備
grpc-gateway使用完全的Go語言進(jìn)行開發(fā),所以安裝起來也非常簡單,首先需要獲取相關(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
最終可以看到以下文件
二,編寫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)開啟") s.Serve(lis) }
運(yùn)行g(shù)rpc服務(wù)端:
go build grpc_service.go ./grpc_service
編寫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ù)開啟") 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)行壓測
http -> go -> grpc -> go
http -> go -> http -> grpc_gateway -> grpc -> go
六,總結(jié)
在GO的場景下基本上4倍差距,但是考慮到本身Go在grpc和http上本身就有3.5倍的差距,本身在同等HTTP的情況下經(jīng)過grpc-gateway和不經(jīng)過直接到API差距大概在20~30%左右,這樣的性能消耗帶來的是兼容HTTP并且還可以自動(dòng)生成swagger(還可以作為調(diào)試工具),何樂而不為呢?
原文鏈接:https://juejin.cn/post/6844904074454925319
相關(guān)推薦
- 2022-08-16 Hive導(dǎo)入csv文件示例_數(shù)據(jù)庫其它
- 2022-08-06 C語言基于EasyX繪制時(shí)鐘_C 語言
- 2022-11-23 Android開發(fā)Jetpack?Compose元素Modifier特性詳解_Android
- 2023-07-09 抽象數(shù)據(jù)結(jié)構(gòu)與表抽象數(shù)據(jù)結(jié)構(gòu)表
- 2022-09-30 關(guān)于react中列表渲染的局部刷新問題_React
- 2022-05-27 一起來學(xué)習(xí)C語言的程序環(huán)境與預(yù)處理_C 語言
- 2022-12-12 Android?Google?AutoService框架使用詳解_Android
- 2022-06-04 C#?XML基礎(chǔ)入門小結(jié)(XML文件內(nèi)容增刪改查清)_C#教程
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支