c python通信protobuf_Protobuf、gRPC入门实战(Python)(完善中...)

一、背景介绍:

由于本人最近在研究基于TensorFlow的分布式计算相关的问题。需要基于现有的代码做一些定制化的修改。在学习TensorFlow源码实现的过程中,了解到了关于TensorFlow的通信的方法。由于本人完全是通过网络上查找资料自学的,期间也走了一些弯路。由于网上的帖子多是一些大佬写的,因此对于像本人这样的小白而言,理解起来难免会有一些费劲。因此,写这篇文章来给大家分享一下我自己的心得,也希望能给大家的学习带来一些便利。

二、名词及相关概念:

2.1 Protobuf:

Protobuf 是一种数据交换格式,定义接口和数据类型。可以理解为一种定制化的通讯协议。

由三部分组成:proto 文件: 使用的 proto 语法的文本文件, 用来定义数据格式。

protoc: protobuf 编译器(compile), 将 proto 文件编译成不同语言的实现, 这样不同语言中的数据就可以和 protobuf 格式的数据进行交互。

protobuf 运行时(runtime): protobuf 运行时所需要的库, 和 protoc 编译生成的代码进行交互。

2.2 gRPC:

gRPC是什么可以用官网的一句话来概括A high-performance, open-source universal RPC framework

所谓RPC(remote procedure call 远程过程调用)框架实际是提供了一套机制,使得应用程序之间可以进行通信,而且也遵从server/client模型。使用的时候客户端调用server端提供的接口就像是调用本地的函数一样。如下图所示就是一个典型的RPC结构图。gRPC通信结构图

2.2.1 使用场景需要对接口进行严格约束的情况,比如我们提供了一个公共的服务,很多人,甚至公司外部的人也可以访问这个服务,这时对于接口我们希望有更加严格的约束,我们不希望客户端给我们传递任意的数据,尤其是考虑到安全性的因素,我们通常需要对接口进行更加严格的约束。这时gRPC就可以通过protobuf来提供严格的接口约束。

对于性能有更高的要求时。有时我们的服务需要传递大量的数据,而又希望不影响我们的性能,这个时候也可以考虑gRPC服务,因为通过protobuf我们可以将数据压缩编码转化为二进制格式,通常传递的数据量要小得多,而且通过http2我们可以实现异步的请求,从而大大提高了通信效率。

2.2.2 grpc 的4 种通信方式:

根据不同的业务场景, grpc 支持 4 种通信方式:客服端一次请求, 服务器一次应答

客服端一次请求, 服务器多次应答(流式)

客服端多次请求(流式), 服务器一次应答

客服端多次请求(流式), 服务器多次应答(流式)

官方提供了一个 route guide service 的 demo, 应用到了这 4 种通信方式, 具体的业务如下:数据源: json 格式的数据源, 存储了很多地点, 每个地点由经纬度(point)和地名(location)组成

通信方式 1: 客户端请求一个地点是否在数据源中

通信方式 2: 客户端指定一个矩形范围(矩形的对角点坐标), 服务器返回这个范围内的地点信息

通信方式 3: 客户端给服务器发送多个地点信息, 服务器返回汇总信息(summary)

通信方式 4: 客户端和服务器使用地点信息 聊天(chat)

三、代码实战:

3.1 代码相关流程:

其中:(filename)_pb2.py: 用来和 protobuf 数据进行交互

(filename)_pb2_grpc.py: 用来和 grpc 进行交互

3.2 配置环境:

# 安装 grpc 相关的 python 模块

pip install grpcio

# 安装 python 下的 protoc 编译器, 使用 protoc 编译 proto 文件, 生成 python 语言的实现

pip install grpcio-tools

编译proto文件:

python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. helloworld.proto

python -m grpc_tools.protoc: python 下的 protoc 编译器通过 python 模块(module) 实现, 所以说这一步非常省心

--python_out=. : 编译生成处理 protobuf 相关的代码的路径, 这里生成到当前目录

--grpc_python_out=. : 编译生成处理 grpc 相关的代码的路径, 这里生成到当前目录

-I. helloworld.proto : proto 文件的路径, 这里的 proto 文件在当前目录

3.3 proto文件代码实现及相关介绍:

// [python quickstart](https://grpc.io/docs/quickstart/python.html#run-a-grpc-application)

// python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. helloworld.proto

// helloworld.proto

syntax = "proto3";

service Greeter {

rpc SayHello(HelloRequest) returns (HelloReply) {}

rpc SayHelloAgain(HelloRequest) returns (HelloReply) {}

}

message HelloRequest {

string name = 1;

}

message HelloReply {

string message = 1;

}

3.4 服务器端代码实现与介绍:

from concurrent import futures

import time

import grpc

import helloworld_pb2

import helloworld_pb2_grpc

# 实现 proto 文件中定义的 GreeterServicer

class Greeter(helloworld_pb2_grpc.GreeterServicer):

# 实现 proto 文件中定义的 rpc 调用

def SayHello(self, request, context):

return helloworld_pb2.HelloReply(message = 'hello {msg}'.format(msg = request.name))

def SayHelloAgain(self, request, context):

return helloworld_pb2.HelloReply(message='hello {msg}'.format(msg = request.name))

def serve():

# 启动 rpc 服务

server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)

server.add_insecure_port('[::]:50051')

server.start()

try:

while True:

time.sleep(60*60*24) # one day in seconds

except KeyboardInterrupt:

server.stop(0)

if __name__ == '__main__':

serve()

3.5 客户端代码实现与介绍:

import grpc

import helloworld_pb2

import helloworld_pb2_grpc

def run():

# 连接 rpc 服务器

channel = grpc.insecure_channel('localhost:50051')

# 调用 rpc 服务

stub = helloworld_pb2_grpc.GreeterStub(channel)

response = stub.SayHello(helloworld_pb2.HelloRequest(name='czl'))

print("Greeter client received: " + response.message)

response = stub.SayHelloAgain(helloworld_pb2.HelloRequest(name='daydaygo'))

print("Greeter client received: " + response.message)

if __name__ == '__main__':

run()

参考与引用:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
gRPC 是一种高性能、开源的 RPC 框架,支持多种编程语言。在 Python ,我们可以使用 gRPC 提供远程过程调用服务。 以下是在 Python 使用 gRPC 的基本步骤: 1. 安装 gRPC:使用 pip install grpcio 命令安装 gRPC。 2. 定义服务和消息:使用 proto3 编写 .proto 文件,定义服务和消息。 3. 生成代码:使用 protoc 命令生成 Python 代码。 4. 实现服务:在 Python 实现服务端和客户端。 5. 启动服务:启动服务端程序。 6. 调用服务:在客户端程序调用远程服务。 以下是一个简单的示例,演示如何在 Python 使用 gRPC: 1. 定义服务和消息 ```protobuf syntax = "proto3"; package helloworld; // 定义消息 message HelloRequest { string name = 1; } message HelloReply { string message = 1; } // 定义服务 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } ``` 2. 生成代码 使用以下命令生成 Python 代码: ```bash python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. helloworld.proto ``` 3. 实现服务 在 Python 实现服务端和客户端。 ```python import grpc import helloworld_pb2 import helloworld_pb2_grpc class Greeter(helloworld_pb2_grpc.GreeterServicer): def SayHello(self, request, context): return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) def serve(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port('[::]:50051') server.start() server.wait_for_termination() if __name__ == '__main__': serve() ``` ```python import grpc import helloworld_pb2 import helloworld_pb2_grpc def run(): with grpc.insecure_channel('localhost:50051') as channel: stub = helloworld_pb2_grpc.GreeterStub(channel) response = stub.SayHello(helloworld_pb2.HelloRequest(name='world')) print("Greeter client received: " + response.message) if __name__ == '__main__': run() ``` 4. 启动服务 在终端运行以下命令启动服务: ```bash python greeter_server.py ``` 5. 调用服务 在终端运行以下命令调用服务: ```bash python greeter_client.py ``` 以上是在 Python 使用 gRPC 的基本步骤。在生产环境,我们需要考虑更多的实现细节,例如错误处理、认证和安全等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值