使用grpc實(shí)現(xiàn)golang后端和python服務(wù)間通信
grpc前言
gRPC是Google 開發(fā)的高性能、開源的遠(yuǎn)程過程調(diào)用(RPC)框架,基于 HTTP/2 協(xié)議進(jìn)行通信,使用 Protocol Buffers(protobuf)作為接口定義語(yǔ)言,可以看為一種協(xié)議。
grpc可以用于各種不同服務(wù)間的通信,屏蔽底層細(xì)節(jié)(如編程語(yǔ)言,操作系統(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庫(kù)
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)庫(kù)
pip install grpcio pip install grpcio-tools
py的服務(wù)端代碼grpc相關(guān)的代碼較為簡(jiǎ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實(shí)現(xiàn)監(jiān)控屏幕界面內(nèi)容變化并發(fā)送通知
這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)實(shí)時(shí)監(jiān)控屏幕上的信息是否發(fā)生變化并發(fā)送通知,文中的示例代碼講解詳細(xì),感興趣的可以了解一下2023-04-04
Python實(shí)現(xiàn)ODT自動(dòng)化轉(zhuǎn)換為DOCX的完整指南
在數(shù)字化辦公場(chǎng)景中,文檔格式的兼容性問題始終困擾著用戶,本文將通過Python實(shí)現(xiàn)ODT到DOCX的自動(dòng)化轉(zhuǎn)換,并延伸探討PDF信息提取技術(shù),感興趣的小伙伴可以了解下2026-02-02
11行Python代碼實(shí)現(xiàn)解密摩斯密碼
摩爾斯電碼是一種時(shí)通時(shí)斷的信號(hào)代碼,通過不同的排列順序來表達(dá)不同的英文字母、數(shù)字和標(biāo)點(diǎn)符號(hào)。本文將通過Python代碼來實(shí)現(xiàn)解密摩斯密碼,感興趣的可以學(xué)習(xí)一下2022-04-04
python模擬鼠標(biāo)點(diǎn)擊和鍵盤輸入的操作
這篇文章主要介紹了python模擬鼠標(biāo)點(diǎn)擊和鍵盤輸入的操作,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08
Django 自定義權(quán)限管理系統(tǒng)詳解(通過中間件認(rèn)證)
這篇文章主要介紹了Django 自定義權(quán)限管理系統(tǒng)詳解(通過中間件認(rèn)證),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03
import?paddle報(bào)錯(cuò)的成功解決方法
最近安裝paddle的時(shí)候遇到了些問題,這里給大家總結(jié)下,下面這篇文章主要給大家介紹了關(guān)于import?paddle報(bào)錯(cuò)的成功解決方法,需要的朋友可以參考下2023-06-06
在Python反編譯中批量pyc轉(zhuǎn)?py的實(shí)現(xiàn)代碼
這篇文章主要介紹了在Python反編譯中批量pyc轉(zhuǎn)?py的實(shí)現(xiàn)代碼,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02

