当前位置: 首页 > 工具软件 > python-grpc > 使用案例 >

python grpc多进程_python-gRPC使用

解浩渺
2023-12-01

什么是gRPC

在 gRPC 里客户端 应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根 能够像服务端一样的方法。

如何使用grpc在一个 .proto 文件内定义服务。

用 protocol buffer 编译器生成服务器和客户端代码。

使用 gRPC 的 Python API 为你的服务实现一个简单的客户端和服务器

grpc优势使用protobuf做数据交换,有优势。

1:序列化后体积相比Json和XML很小,适合网络传输

2:支持跨平台多语言

3:消息格式升级和兼容性还不错

4:序列化反序列化速度很快,快于Json的处理速速

使用REST或者GraphQL进行外部通信,使用gRPC进行内部通信,使得内部接口不会暴露。

基于HTTP2带来的优势

1: 基于HTTP2可以使用连接复用

HTTP1.0传输数据每次都需要重新建立连接,HTTP1.1增加keep-alive可以使得连接复用总而言之,即是减少握手次数,SSL认证握手次数。

2: 减少header头部大小

http1.x的header由于cookie和user agent很容易膨胀,而且每次都要重复发送。

http2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。高效的压缩算法可以很大的压缩header,减少发送包的数量从而降低延迟。

3: HTTP2使用流与多路复用技术

流(stream)就是HTTP2连接的双向帧(frame)序列 ,每一个http request会创建一个自己的stream,http response会在同一个stream中返回。多路复用(MultiPlexing),即连接共享。之所以可以复用,是因为每个流(stream)高度独立,堵塞的流(stream)不会影响其它stream的处理。一个连接上可以有多个流(stream),每个流(stream)的帧(frame)可以随机的混杂在一起,接收方可以根据stream id将frame再归属到各自不同的request里面。

4:Server Push

服务器推,参考websocket

grpc 的基础: protobuf 3指定proto版本,如果没有指定默认使用proto2syntax = "proto3";

定义消息类型,也就是请求参数和返回参数,例如想定义一个搜索请求的消息格式 例如: 我们定义一个搜索请求

message SearchRequest { string query = 1; int32 page_number = 2; int32 result_per_page = 3; // 注释} message SearchResponse { ...}

3. 定义服务

如果想要将消息类型用在RPC(远程方法调用)系统中,可以在.proto文件中定义一个RPC服务接口,protocol buffer编译器将会根据所选择的不同语言生成服务接口代码及存根。如,想要定义一个RPC服务并具有一个方法,该方法能够接收 SearchRequest并返回一个SearchResponse,此时可以在.proto文件中进行如下定义:

service SearchService { rpc Search (SearchRequest) returns (SearchResponse); // 如果需要流式响应/返回 则需要在message类型变量前加 stream}

4. protobuf生成了什么?

对Python来说,有点不太一样——Python编译器为.proto文件中的每个消息类型生成一个含有静态描述符的模块,,该模块与一个元类(metaclass)在运行时(runtime)被用来创建所需的Python数据访问类。

5. 之后我们就可以通过PythonAPI进行调用

简单 RPC

客户端使发送请求到服务器并等待响应返回,就像平常的函数调用一样。

service FormatData { // 客户端一次请求, 服务器一次应答 rpc DoFormat(Data) returns (Data){}}

# 服务端

class FormatData(data_pb2_grpc.FormatDataServicer):

def DoFormat(self, request, context):

# 客户端一次请求, 服务器一次应答

str = request.text

return data_pb2.Data(text=str.upper())

# 客户端

def run():

conn = grpc.insecure_channel(_HOST + ':' + _PORT)

client = data_pb2_grpc.FormatDataStub(channel=conn)

response = client.DoFormat(data_pb2.Data(text='hello,world!'))

应答流式 RPC

客户端发送请求到服务器,拿到一个stream去读取返回的消息序列。 客户端读取返回的stram,直到里面没有任何消息。

service FormatDataToStream { // 客户端一次请求, 服务器多次应答 rpc DoFormat(Data) returns (stream Data){}}

# 服务端

class FormatDataToStream(data_pb2_grpc.FormatDataToStreamServicer):

def ListDoFormat(self, request, context):

# 客户端一次请求, 服务器多次应答 1-n

str = request.text

for d in range(1, 10):

format_string = "%s" % d + str

yield data_pb2.Data(text=format_string)

# 客户端

def run():

client = data_pb2_grpc.FormatDataToStreamStub(channel=conn)

response = client.DoFormat(data_pb2.Data(text='hello,world!'))

for res in response:

print("1-n received: " + res.text)

请求流式 RPC

客户端写入一个消息序列并将其发送到服务器,同样也是使用steam。一旦客户端完成写入消息,它等待服务器完成读取返回它的响应。通过在 请求 类型前指定 stream 关键字来指定一个客户端的流方法。

双向流式 RPC

两个流独立操作,因此客户端和服务器可以以任意喜欢的顺序读写:比如, 服务器可以在写入响应前等待接收所有的客户端消息,或者可以交替的读取和写入消息,或者其他读写的组合。 每个流中的消息顺序被预留。你可以通过在请求和响应前加 stream 关键字去制定方法的类型。

grpc开发流程撰写proto文件

生成py文件

对client进行编辑,执行

 类似资料: