使用grpc實(shí)現(xiàn)golang后端和python服務(wù)間通信
grpc前言
gRPC是Google 開發(fā)的高性能、開源的遠(yuǎn)程過程調(diào)用(RPC)框架,基于 HTTP/2 協(xié)議進(jìn)行通信,使用 Protocol Buffers(protobuf)作為接口定義語言,可以看為一種協(xié)議。
grpc可以用于各種不同服務(wù)間的通信,屏蔽底層細(xì)節(jié)(如編程語言,操作系統(tǒng)等)
由于我的一個(gè)go后端(也可以不是go)需要實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)相關(guān)的功能,我要調(diào)用一個(gè)python的服務(wù),于是想到了使用grpc的方式。
初次接觸,將從0介紹到功能實(shí)現(xiàn)。
感謝官方的文檔
https://grpc.io/docs/languages/go/quickstart/
主要流程
定義.proto文件:創(chuàng)建一個(gè) .proto 文件,定義圖數(shù)據(jù)和 GCN 結(jié)果的消息類型以及服務(wù)接口。
生成 gRPC 代碼:使用 Protocol Buffers 編譯器 protoc,根據(jù) .proto 文件生成 Go 和 Python 的 gRPC 代碼。
實(shí)現(xiàn) Python 服務(wù)器:在 Python 中實(shí)現(xiàn) gRPC 服務(wù)器,接收來自 Go 客戶端的圖數(shù)據(jù),進(jìn)行 GCN 處理,并返回處理結(jié)果。
實(shí)現(xiàn) Go 客戶端:在 Go 中實(shí)現(xiàn) gRPC 客戶端,發(fā)送圖數(shù)據(jù)到 Python 服務(wù)器,并接收處理結(jié)果。
安裝protoc解釋器
grpc是通過pb(protocolbuffer)這個(gè)協(xié)議工作的,首先安裝protoc的解釋器,并將其bin文件夾添加到環(huán)境變量。
地址:https://github.com/protocolbuffers/protobuf/releases
下載后解壓到任意文件夾位置,然后將解壓后的bin文件夾添加到環(huán)境變量。
打開cmd輸入protoc有數(shù)據(jù)返回就ok了。
為了在項(xiàng)目中使用protoc的一些指令可以正常工作,還有把bin文件下的protoc.exe文件復(fù)制一份到C:\Windows\System32文件夾下。
順便一提,為了proto文件可以在vscode高亮顯示,可以安裝官方的插件:protobuf,作者:pbkit
go端工作
首先安裝go的grpc庫
go get -u google.golang.org/grpc
然后安裝可以將proto文件自動(dòng)解析為go文件的解釋器:
go install google.golang.org/protobuf/cmd/protoc-gen-go go install google.golang.org/grpc/cmd/protoc-gen-go-grpc
定義proto文件 gcn.proto:
其中g(shù)o_package是指定生成的文件位置和文件所在包名。“.” 表示文件生成在當(dāng)前目錄,“;”表示參數(shù)分割,后面的proto是將生成文件放在proto包中。
還有更多可選參數(shù),自行參考官方
go_package:指定生成 Go 代碼時(shí)的包路徑,格式為 option go_package = “package_path”;,用于將生成的代碼放置在指定的 Go 包中。
java_package:指定生成 Java 代碼時(shí)的包路徑,格式為 option java_package = “package_path”;,用于將生成的代碼放置在指定的 Java 包中。
java_outer_classname:指定生成 Java 代碼時(shí)的外部類名,格式為 option java_outer_classname = “ClassName”;,用于指定生成的 Java 類的外部類名。
cc_generic_services:指定是否生成 C++ 通用服務(wù)(generic services),格式為 option cc_generic_services = true; 或 option cc_generic_services = false;,默認(rèn)為
true。
cc_enable_arenas:指定是否啟用 C++ arenas 內(nèi)存管理,格式為 option cc_enable_arenas = true; 或 option cc_enable_arenas = false;,默認(rèn)為 false。
optimize_for:指定優(yōu)化選項(xiàng),可以是 SPEED、CODE_SIZE 或 LITE_RUNTIME,格式為 option optimize_for = SPEED;,默認(rèn)為 SPEED。
deprecated:指定消息或字段已過時(shí),格式為 option deprecated = true;。
rpc_timeout:指定 gRPC 調(diào)用的超時(shí)時(shí)間,格式為 option rpc_timeout = “10s”;,表示超時(shí)時(shí)間為 10秒。
gcn.proto協(xié)議文件具體定義為:
syntax = "proto3"; option go_package = ".;proto"; message Node { string id = 1; repeated float features = 2; } message Edge { string source_id = 1; string target_id = 2; } message GraphData { repeated Node nodes = 1; repeated Edge edges = 2; } message GCNResult { map<string, float> node_scores = 1; } service GCNService { rpc ProcessGraph(GraphData) returns (GCNResult); }
我這里是用來處理圖數(shù)據(jù)。
接下來生成 gRPC 代碼:
protoc --go_out=. --go_opt=paths=source_relative your_proto_file.proto
protoc --go-grpc_out=. --go-grpc_opt=paths=source_relative your_proto_file.proto
會(huì)生成兩個(gè)文件gcn.pb.go和gcn_grpc.pb.go
前者生成的文件,包含所有pb協(xié)議的go代碼,將數(shù)據(jù)格式寫為go的結(jié)構(gòu)體形式。包含填充、序列化,檢索請(qǐng)求和響應(yīng)消息類型。
后者包含客戶端使用中定義的方法,調(diào)用的接口類型。以及服務(wù)端要實(shí)現(xiàn)的接口類型。包含創(chuàng)建客戶端服務(wù)和服務(wù)端服務(wù)的方法。
請(qǐng)注意,無論go后端作為請(qǐng)求grpc的一方(client)還是做出響應(yīng)的一方(server),這兩個(gè)文件都是必須生成的。
使用client := pb.NewXXXXServiceClient(conn)的方式創(chuàng)建客戶端
最后就是完成go端的grpc請(qǐng)求代碼,每次請(qǐng)求都創(chuàng)建一個(gè)grpc的連接,請(qǐng)求完畢defer斷開:
func GCN_request() (map[string]float32, error) { conn, err := grpc.Dial("localhost:9999", grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { // Failed to connect to gcnserver(py) by grpc return nil, err } defer conn.Close() client := pb.NewGCNServiceClient(conn) // 創(chuàng)建一個(gè)實(shí)例的圖數(shù)據(jù) G_example := &pb.GraphData{ Nodes: []*pb.Node{ {Id: "node1", Features: []float32{0.1, 0.2, 0.3}}, {Id: "node2", Features: []float32{0.4, 0.5, 0.6}}, }, Edges: []*pb.Edge{ {SourceId: "node1", TargetId: "node2"}, }, } // 發(fā)送請(qǐng)求并接收響應(yīng) result, err := client.ProcessGraph(context.Background(), G_example) if err != nil { // Error calling ProcessGraph return nil, err } return result.NodeScores, err }
最后的最后別忘了創(chuàng)建一個(gè)路由調(diào)用這個(gè)方法。
python端工作
py同樣安裝grpc相關(guān)庫
pip install grpcio pip install grpcio-tools
py的服務(wù)端代碼grpc相關(guān)的代碼較為簡潔,重點(diǎn)在于數(shù)據(jù)處理。將其服務(wù)端口和grpc客戶端的請(qǐng)求端口保持一致。
部分代碼取自官方示例。
import grpc from concurrent import futures from proto import gcn_pb2_grpc, gcn_pb2 class GCNServicer(gcn_pb2_grpc.GCNServiceServicer): def ProcessGraph(self, request, context): # Process graph data using GCN and return result # example: return gcn_pb2.GCNResult(node_scores={"node1": 0.5, "node2": 0.8}) def server(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) gcn_pb2_grpc.add_GCNServiceServicer_to_server(GCNServicer(), server) server.add_insecure_port('[::]:9999') server.start() print('gRPC 服務(wù)端已開啟,端口為9999...') server.wait_for_termination() if __name__ == '__main__': server()
啟動(dòng)
做好了以上工作就大功告成了,啟動(dòng)兩個(gè)服務(wù)即可
go run main.go
python server.py
然后訪問定義的路由地址,如下顯示,nice~
到此這篇關(guān)于使用grpc實(shí)現(xiàn)golang后端和python服務(wù)間通信的文章就介紹到這了,更多相關(guān)go python服務(wù)間通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python調(diào)用騰訊API進(jìn)行人像動(dòng)漫化效果實(shí)例
最近上網(wǎng)的時(shí)候看到了一個(gè)有趣的東西,叫做人物動(dòng)漫化,嘗試著用python實(shí)現(xiàn)了,所以下面這篇文章主要給大家介紹了關(guān)于Python調(diào)用騰訊API進(jìn)行人像動(dòng)漫化效果的相關(guān)資料,需要的朋友可以參考下2023-06-06python 多進(jìn)程通信模塊的簡單實(shí)現(xiàn)
這篇文章主要介紹了python 多進(jìn)程通信模塊的簡單實(shí)現(xiàn),需要的朋友可以參考下2014-02-02使用用Pyspark和GraphX實(shí)現(xiàn)解析復(fù)雜網(wǎng)絡(luò)數(shù)據(jù)
GraphX是Spark提供的圖計(jì)算API,它提供了一套強(qiáng)大的工具,這篇文章將詳細(xì)為大家介紹如何在Python?/?pyspark環(huán)境中使用graphx進(jìn)行圖計(jì)算,感興趣的可以了解下2024-01-01解決windows上安裝tensorflow時(shí)報(bào)錯(cuò),“DLL load failed: 找不到指定的模塊”的問題
這篇文章主要介紹了解決windows上安裝tensorflow時(shí)報(bào)錯(cuò),“DLL load failed: 找不到指定的模塊”的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05django框架創(chuàng)建應(yīng)用操作示例
這篇文章主要介紹了django框架創(chuàng)建應(yīng)用操作,結(jié)合實(shí)例形式分析了Django框架的安裝、創(chuàng)建項(xiàng)目、創(chuàng)建數(shù)據(jù)庫及創(chuàng)建應(yīng)用相關(guān)操作技巧,需要的朋友可以參考下2019-09-09Kwargs傳遞給Python 中的另一個(gè)函數(shù)實(shí)現(xiàn)方法
Python 列出了可以傳遞給程序中的函數(shù)的兩種類型的參數(shù), 非關(guān)鍵字參數(shù)**args和關(guān)鍵字參數(shù) **kwargs ,在本文中,我們將討論如何使用關(guān)鍵字參數(shù)及如何將關(guān)鍵字參數(shù)傳遞給另一個(gè)函數(shù),感興趣的朋友跟隨小編一起看看吧2023-08-08python中CURL 和python requests的相互轉(zhuǎn)換實(shí)現(xiàn)
本文主要介紹了python中CURL 和python requests的相互轉(zhuǎn)換實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03Python的NLTK模塊詳細(xì)介紹與實(shí)戰(zhàn)案例
自然語言處理庫NLTK在Python中的應(yīng)用廣泛,提供了分詞、詞性標(biāo)注、句法分析等多種功能,本文介紹了NLTK的核心功能、基本概念以及通過具體實(shí)戰(zhàn)案例(如文本分詞、去除停用詞、詞干提取等)展示了其在NLP任務(wù)中的實(shí)際應(yīng)用2024-09-09