python 利用gRPC完成遠程調用c++

Python Django寫的後臺,想要調用小夥伴的c++模塊方法,目前想到三種解決方案:http,gRPC,本地調用(ctypes,SWIG)
出於以下考慮:

  • 後臺與模型模塊分離部署(部分模型模塊對GPU,顯存等有各類要求)
  • 跨語言(Python 調用 c++方法)
  • 簡單,學習時長短

決定學習並嘗試用gRPC完成此次調用。

步驟

  • 編寫.proto文件定義服務,規定接口樣式。
  • 通過.proto文件的服務定義中生成gRPC客戶端和服務器端的接口(python生成***_pb2.py和***_pb2_grpc.py),可以通過protocol buffer的編譯器protoc以及一個特殊的gRPC Python插件來完成(不同語言插件、包不同)
  • 使用gRPC的API完成不同語言的client和server

安裝

#gRPC 的安裝:
$ pip install grpcio
#安裝 ProtoBuf 相關的 python 依賴庫:
$ pip install protobuf
#安裝 python grpc 的 protobuf 編譯工具:
$ pip install grpcio-tools

grpc git examples(python)

helloworld.proto

// Filename: helloworld.proto
syntax="proto3";
package helloworld;

//Greeter:服務名稱;SayHello:函數名;
//gRPC允許定義4種類型的service方法:
//簡單RPC;應答流式RPC;請求流式RPC;雙向流式RPC
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}
//輸入參數
// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}
//輸出參數
// The response message containing the greetings
message HelloReply {
  string message = 1;
}

生成接口文件:helloworld_pb2.py,helloworld_pb2_grpc.py

#-I:運行目錄路徑名
#--python_out:生成Python源文件
#--grpc_out:生成grpc源文件
#--plugin:指定要使用的插件可執行文件。這裏是Python路徑
#.是當前目錄  ..是當前目錄的上層目錄
$ protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc='which grpc_python_plugin' ../../protos/route_guide.proto

sercer.py

from concurrent import futures
import time
import logging

import grpc

import helloworld_pb2
import helloworld_pb2_grpc

_ONE_DAY_IN_SECONDS = 60 * 60 * 24

#Greeter:服務名;SayHello:方法名
class Greeter(helloworld_pb2_grpc.GreeterServicer):

    def SayHello(self, request, context):
    	#請求內容在request中,取數據:request.name
        return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)


def serve():
	#max_workers:最大連接數
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
    #服務啓動的ip和端口
    server.add_insecure_port('[::]:50051')
    server.start()
    try:
        while True:
            time.sleep(_ONE_DAY_IN_SECONDS)
    except KeyboardInterrupt:
        server.stop(0)


if __name__ == '__main__':
    logging.basicConfig()
    serve()

client.py

from __future__ import print_function
import logging

import grpc

import helloworld_pb2
import helloworld_pb2_grpc


def run():
	#請求的ip和端口地址
    with grpc.insecure_channel('localhost:50051') as channel:
        stub = helloworld_pb2_grpc.GreeterStub(channel)
        #SayHello:請求方法;name:請求參數
        response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
    print("Greeter client received: " + response.message)


if __name__ == '__main__':
    logging.basicConfig()
    run()

參考
gRPC官方文檔中文版_V1.0
http://doc.oschina.net/grpc?t=60138
Python:如何將proto文件編譯爲python文件
https://blog.csdn.net/Wendy_LWZ/article/details/80654703
Python:GRPC接口編寫之如何編寫服務端與客戶端
https://blog.csdn.net/Wendy_LWZ/article/details/81330799
gRPC 在Python中的應
https://blog.csdn.net/alanguoo/article/details/78635260

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章