如何解决如何在python中配置gRPC HTTP / 2流控制
我有一个带有以下协议的gRPC服务器:
syntax = "proto3";
service MyServicer {
rpc DoSomething(stream InputBigData) returns (stream OutputBigData) {}
}
message InputBigData {
bytes data = 1;
}
message OutputBigData {
bytes data = 1;
}
然后使用以下Python代码创建我的服务器:
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10),options=[('grpc.max_receive_message_length',-1),('grpc.max_send_message_length',-1))])
max_receive_message_length和max_send_message_length设置为-1,以允许传输大消息(通常为8Mb)。客户端还定义了相同的选项。
情况1:考虑客户端向服务器发送InputBigData的速率高于服务器所能承受的速率。如何配置输入流中可以排队多少个InputBigData(或字节)?
第2种情况:考虑到客户端从服务器读取响应OutputBigData的速率低于客户端承受的速度。如何配置输出流中可以排队多少个OutputBigData(或字节)?
我知道gRPC流控制基于HTTP / 2:https://httpwg.org/specs/rfc7540.html#FlowControl 我试图将grpc.http2.write_buffer_size设置为67108864(似乎是最大值),但是什么也没发生。
这里是突出显示情况2的实现:
# server.py
from concurrent import futures
import grpc
import myservicer_pb2_grpc,myservicer_pb2
class MyServicer(myservicer_pb2_grpc.MyServicer):
def DoSomething(self,request_iterator,target,**kwargs):
big_data = b'0' * 1920*1080*4
for r in request_iterator:
print("server received input big data")
yield myservicer_pb2.OutputBigData(data=big_data)
print("server sent output big data")
if __name__ == '__main__':
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10),-1)])
myservicer_pb2_grpc.add_MyServicerServicer_to_server(
MyServicer(),server)
server.add_insecure_port("[::]:50051")
server.start()
server.wait_for_termination()
# client.py
import time
import grpc
import myservicer_pb2_grpc
import myservicer_pb2
def big_data_generator():
big_data = b'0' * 1920*1080*4
for i in range(100):
yield myservicer_pb2.InputBigData(data=big_data)
def run():
with grpc.insecure_channel('localhost:50051',options=[('grpc.max_send_message_length',('grpc.max_receive_message_length',-1)]) as channel:
stub = myservicer_pb2_grpc.MyServicerStub(channel)
res = stub.DoSomething(big_data_generator())
for r in res:
print("Client received data")
time.sleep(10)
if __name__ == '__main__':
run()
10秒后,我的服务器输出为:
server received input big data
server sent output big data
server received input big data
server sent output big data
server received input big data
我的客户输出是:
Client received data
我的服务器收到3个InputBigData并发送了2个OutputBigData。现在它被阻塞,直到客户端使用输出数据。在这种情况下,我想增加(2或3倍)输出缓冲区大小,以便即使客户端延迟使用结果也可以继续处理更多输入数据。
解决方法
感谢详细的问题。我尝试了您的示例,但仍然无法调整gRPC来自由增加其窗口大小。
可以在here中找到gRPC通道参数。流量控制实现为here,可能会影响流量控制的只有几种,
-
grpc.http2.bdp_probe=0
:禁用自动窗口增加 -
grpc.http2.max_frame_size
:HTTP / 2最大帧大小 -
grpc.http2.write_buffer_size
:并不是真正的流控制选项,它用于GRPC_WRITE_BUFFER_HINT(写而不会阻塞)。另外,gRPC Python还不支持GRPC_WRITE_BUFFER_HINT
没有可触发窗口大小更新的参数。默认窗口大小为64KB。 gRPC将通过BDP估算来增加窗口大小。例如,在我的笔记本电脑上,客户端出站窗口大小增加到8380679(〜8MB)。但是我还没有找到一种手动干预此过程的方法。
因此,不幸的是,您可能需要应用程序级缓冲。您可以在异步中使用协程,也可以在客户端和服务器端使用带有线程安全队列的线程。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。