免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
gRPC學(xué)習(xí)之五:gRPC-Gateway實戰(zhàn)

歡迎訪問我的GitHub

https://github.com/zq2599/blog_demos

內(nèi)容:所有原創(chuàng)文章分類和匯總,及配套源碼,涉及Java、Docker、Kubernetes、DevOPS等;

本篇概覽

  • 本文《gRPC學(xué)習(xí)》系列的第五篇,gRPC常用于服務(wù)端之間的相互調(diào)用,如果想把服務(wù)暴露給前端,雖然動手修改服務(wù)端也能實現(xiàn),但似乎增加了不少工作量,此時還可以選擇gRPC-Gateway方式來快速將gRPC服務(wù)以http的方式暴露出來;
  • gRPC-Gateway原理如下圖,借助grpc-gateway插件,可以基于proto文件生成反向代理(Reverse Proxy)的代碼,這個反向代理運行起來后,對外提供RESTful服務(wù),收到RESTful請求后通過gRPC調(diào)用原來的gRPC服務(wù):
  • 本文展示了gRPC-Gateway環(huán)境搭建、開發(fā)、驗證的整個過程,由以下步驟組成:
  1. 極速搭建gRPC-Gateway環(huán)境;
  2. 編寫proto文件;
  3. 根據(jù)proto文件生成gRPC、gRPC-Gateway源碼;
  4. 添加業(yè)務(wù)代碼;
  5. 編譯、運行、驗證;

提前說明文件和目錄

  • 本次實戰(zhàn)在$GOPATH/src目錄下新增文件夾helloworld,里面總共有以下內(nèi)容:
[golang@centos7 src]$ tree helloworld/helloworld/├── gateway│ └── helloworld.gw.go├── helloworld.pb.go├── helloworld.pb.gw.go├── helloworld.proto├── helloworld.swagger.json└── server └── server.go
  • 準(zhǔn)備工作完成,接下來正式開始開發(fā);

前提條件

  • 本文的所有操作都沒有用到root賬號,而是前文創(chuàng)建的golang賬號;
  • 請參照以下兩篇文章將GO環(huán)境和gRPC環(huán)境搭建好:
  1. gRPC學(xué)習(xí)之一:CentOS7部署和設(shè)置GO
  2. gRPC學(xué)習(xí)之二:GO的gRPC開發(fā)環(huán)境準(zhǔn)備

極速搭建gRPC-Gateway環(huán)境

  • 所謂的搭建gRPC-Gateway環(huán)境,其實是完成以下三件事:
  1. 在搭建環(huán)境時參考了一些網(wǎng)上的文章,結(jié)果遇到了各種問題一直沒有成功(我當(dāng)然不會認(rèn)為文章有問題,必須認(rèn)識到是自己能力不足的原因所致);
  2. 經(jīng)過反復(fù)折騰后終于成功后,我把所有操作做成一個shell腳本,執(zhí)行以下命令即可完成上圖中的所有操作:
curl -o install-grpc-gateway.sh \https://raw.githubusercontent.com/zq2599/blog_demos/master/files/install-grpc-gateway.sh \&& chmod a+x ./install-grpc-gateway.sh \&& ./install-grpc-gateway.sh
  1. 進(jìn)入$GOPATH/bin目錄,可見新增兩個文件protoc-gen-grpc-gatewayprotoc-gen-swagger
[golang@centos7 ~]$ cd $GOPATH/bin[golang@centos7 bin]$ ls -al總用量 26708drwxrwxr-x. 2 golang golang 98 12 19 08:59 .drwxrwxr-x. 5 golang golang 39 12 19 08:21 ..-rwxr-x---. 1 golang golang 5253272 12 19 08:20 protoc-rwxrwxr-x. 1 golang golang 8461147 12 19 08:21 protoc-gen-go-rwxrwxr-x. 1 golang golang 6717463 12 19 08:59 protoc-gen-grpc-gateway-rwxrwxr-x. 1 golang golang 6908535 12 19 08:59 protoc-gen-swagger
  • 現(xiàn)在環(huán)境準(zhǔn)備好了,開始開發(fā);

編寫proto文件

  • $GOPATH/src目錄下,新建文件夾helloworld,里面新建文件helloworld.proto,內(nèi)容如下,有幾處要注意的地方稍后會說:
// 協(xié)議類型syntax = 'proto3';// 包名package helloworld;import 'google/api/annotations.proto';// 定義的服務(wù)名service Greeter {  // 具體的遠(yuǎn)程服務(wù)方法  rpc SayHello (HelloRequest) returns (HelloReply) {    option (google.api.http) = {      post: '/helloworld'      body: '*'    };  }}// SayHello方法的入?yún)?,只有一個字符串字段message HelloRequest {  string name = 1;}// SayHello方法的返回值,只有一個字符串字段message HelloReply {  string message = 1;}
  • 上述proto文件有以下幾處要注意的地方:
  1. 整個文件其實就是以 《gRPC學(xué)習(xí)之三:初試GO版gRPC開發(fā) 》一文中的helloworld.proto為基礎(chǔ),增加了兩處內(nèi)容;
  2. 增加的第一處,是用import關(guān)鍵詞導(dǎo)入google/api/annotations.proto;
  3. 增加的第二處,是SayHello方法的聲明處,增加了option配置,作用是配置SayHello方法對外暴露的RESTful接口的信息;
  4. 在使用protoc-gen-grpc-gateway的時候,上述兩處配置會被識別到并生成對應(yīng)的代碼;

根據(jù)proto文件生成gRPC、gRPC-Gateway源碼

  1. proto文件編寫完成,接下來是生成gRPC、gRPC-Gateway的源碼;
  2. 生成gRPC源碼的命令咱們前面的文章中已經(jīng)用過,如下:
protoc -I. \-I$GOPATH/src \-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \--go_out=plugins=grpc:. \helloworld.proto
  1. 執(zhí)行完成后會在當(dāng)前目錄生成helloworld.pb.go文件;
  2. 執(zhí)行生成gRPC-Gateway源碼的命令:
protoc -I. \-I$GOPATH/src \-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \--grpc-gateway_out=logtostderr=true:. \helloworld.proto
  1. 執(zhí)行完成后會在當(dāng)前目錄生成helloworld.pb.gw.go文件;
  2. 執(zhí)行生成swagger文件的命令:
protoc -I. \-I$GOPATH/src \-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \--swagger_out=logtostderr=true:. \helloworld.proto
  1. 執(zhí)行完成后會在當(dāng)前目錄生成helloworld.swagger.json文件;
  2. 至此,helloworld目錄下一共有這些內(nèi)容:
[golang@centos7 src]$ tree helloworld/helloworld/├── helloworld.pb.go├── helloworld.pb.gw.go├── helloworld.proto└── helloworld.swagger.json0 directories, 4 files
  1. 接下來開始編碼,把運行整個服務(wù)所需的代碼補全;
  2. 由于篇幅限制,本文暫不提及swagger相關(guān)的開發(fā)和驗證,因此生成的helloworld.swagger.json文件本篇用不上,留待下一篇文章使用;

編寫服務(wù)端代碼server.go并啟動

  1. 接下來編寫服務(wù)端代碼server.go,這個和《初試GO版gRPC開發(fā)》中的server.go內(nèi)容一樣;
  2. 在$GOPATH/src/helloworld目錄下新建文件夾server,在此文件夾下新建server.go,內(nèi)容如下,已經(jīng)添加詳細(xì)注釋:
package mainimport ('context''log''net''google.golang.org/grpc'pb 'helloworld')const (port = ':50051')// 定義結(jié)構(gòu)體,在調(diào)用注冊api的時候作為入?yún)ⅲ?/ 該結(jié)構(gòu)體會帶上SayHello方法,里面是業(yè)務(wù)代碼// 這樣遠(yuǎn)程調(diào)用時就執(zhí)行了業(yè)務(wù)代碼了type server struct {// pb.go中自動生成的,是個空結(jié)構(gòu)體pb.UnimplementedGreeterServer}// 業(yè)務(wù)代碼在此寫,客戶端遠(yuǎn)程調(diào)用SayHello時,// 會執(zhí)行這里的代碼func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {// 打印請求參數(shù)log.Printf('Received: %v', in.GetName())// 實例化結(jié)構(gòu)體HelloReply,作為返回值return &pb.HelloReply{Message: 'Hello ' + in.GetName()}, nil}func main() {// 要監(jiān)聽的協(xié)議和端口lis, err := net.Listen('tcp', port)if err != nil {log.Fatalf('failed to listen: %v', err)}// 實例化gRPC server結(jié)構(gòu)體s := grpc.NewServer()// 服務(wù)注冊pb.RegisterGreeterServer(s, &server{})log.Println('開始監(jiān)聽,等待遠(yuǎn)程調(diào)用...')if err := s.Serve(lis); err != nil {log.Fatalf('failed to serve: %v', err)}}
  1. 在server.go所在目錄執(zhí)行g(shù)o run server.go,控制臺提示如下:
[golang@centos7 server]$ go run server.go 2020/12/13 08:20:32 開始監(jiān)聽,等待遠(yuǎn)程調(diào)用...
  1. 此時gRPC的服務(wù)端已啟動,可以響應(yīng)遠(yuǎn)程調(diào)用,接下來開發(fā)反向代理(Reverse Proxy);

編寫反向代理(Reverse Proxy)代碼helloworld.gw.go并啟動

  • 接下來編反向代理(Reverse Proxy)代碼helloworld.gw.go;
  • 在$GOPATH/src/helloworld目錄下新建文件夾gateway,在此文件夾下新建helloworld.gw.go,內(nèi)容如下,有幾處要注意的地方稍后會說明:
package mainimport ('flag''fmt''net/http'gw 'helloworld''github.com/grpc-ecosystem/grpc-gateway/runtime''golang.org/x/net/context''google.golang.org/grpc')var (echoEndpoint = flag.String('echo_endpoint', 'localhost:50051', 'endpoint of YourService'))func run() error {ctx := context.Background()ctx, cancel := context.WithCancel(ctx)defer cancel()mux := runtime.NewServeMux()opts := []grpc.DialOption{grpc.WithInsecure()}err := gw.RegisterGreeterHandlerFromEndpoint(ctx, mux, *echoEndpoint, opts)if err != nil {return err}return http.ListenAndServe(':9090', mux)}func main() {if err := run(); err != nil {fmt.Print(err.Error())}}
  1. 第一處要注意的地方,是調(diào)用http.ListenAndServe監(jiān)聽9090端口,這是對外提供RESTful服務(wù)的端口;
  2. 第二處要注意的地方,是echoEndpoint配置了將外部RESTful請求轉(zhuǎn)發(fā)到server.go提供gRPC服務(wù)的入口處;
  3. 第三處要注意的地方,是調(diào)用了自動生成代碼中的RegisterGreeterHandlerFromEndpoint方法完成上下游調(diào)用的綁定;
  • hellowworld.gw.go所在目錄執(zhí)行go run hellowworld.gw.go,開始監(jiān)聽9090端口的web請求;

驗證

  1. 在本機(jī)上驗證,用curl發(fā)送請求:
curl \-X POST \-d '{'name': 'will'}' \192.168.133.203:9090/helloworld
  1. 收到響應(yīng)如下,這是來自server.go的內(nèi)容,可見http請求通過Reserve Proxy到達(dá)了真實的gRPC服務(wù)提供者,并順利返回給調(diào)用方:
{'message':'Hello will'}
  1. 去看server.go的日志如下:
[golang@centos7 server]$ go run server.go 2020/12/19 14:16:47 開始監(jiān)聽,等待遠(yuǎn)程調(diào)用...2020/12/19 14:24:35 Received: will
  1. 還可以在其他機(jī)器上通過postman驗證,記得關(guān)閉服務(wù)所在機(jī)器的防火墻,請求和響應(yīng)如下,注意按數(shù)字順序設(shè)置和觀察:
  • 至此,將gRPC服務(wù)快速暴露為RESTful服務(wù)的實戰(zhàn)就完成了,如果您正在做這方面的嘗試,希望本文能給您一些參考,接下來的文章咱們一起把swagger補全,讓開發(fā)和聯(lián)調(diào)更加高效;
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
grpc-gateway:grpc轉(zhuǎn)換為http協(xié)議對外提供服務(wù)
golang gRPC 入門
這么大有用嗎?教你通過Scratch創(chuàng)建盡可能小的Docker容器
Go 語言入門教程(一)
【Go語言實戰(zhàn)】 (14) Gin+gRPC 微服務(wù)實現(xiàn)備忘錄 (上) | 用戶模塊
Go項目結(jié)構(gòu)和模塊導(dǎo)入
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服