欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用grpc實(shí)現(xiàn)golang后端和python服務(wù)間通信

 更新時(shí)間:2024年03月26日 10:14:05   作者:空氣力學(xué)先驅(qū)  
gRPC是Google 開發(fā)的高性能、開源的遠(yuǎn)程過程調(diào)用(RPC)框架,本文主要為大家詳細(xì)介紹了如何使用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)文章

最新評(píng)論