python - gRPC Python thread_pool 与 max_concurrent_rpcs

标签 python grpc concurrent.futures

启动 Python grpc.server 时,maximum_concurrent_rpcs 和线程池中使用的 max_workers 有什么区别。如果我想要 maximum_concurrent_rpcs=1,我是否仍应向线程池提供多个线程?

换句话说,我应该将 maximum_concurrent_rpcs 与我的 max_workers 相匹配,还是应该提供比最大并发 RPC 更多的工作人员?

server = grpc.server(
    thread_pool=futures.ThreadPoolExecutor(max_workers=1),
    maximum_concurrent_rpcs=1,
)

最佳答案

如果您的服务器已经同时处理了 maximum_concurrent_rpcs 个请求,并且又收到另一个请求,则该请求将立即被拒绝。

如果 ThreadPoolExecutor 的 max_workers 小于 maximum_concurrent_rpcs 那么在所有线程都忙于处理请求后,下一个请求将被排队,并在一个线程完成它的时候被处理处理。

我也有同样的疑问。为了回答这个问题,我调试了一下 maximum_concurrent_rpcs 会发生什么。调试转到了我的 virtualenv 中的 py36/lib/python3.6/site-packages/grpc/_server.py。搜索 concurrency_exceeded。底线是,如果服务器已经在处理 maximum_concurrent_rpcs 并且另一个请求到达,它将被拒绝:

# ...
elif concurrency_exceeded:
    return _reject_rpc(rpc_event, cygrpc.StatusCode.resource_exhausted,
                        b'Concurrent RPC limit exceeded!'), None
# ...

我用 gRPC Python 快速入门示例进行了尝试:

greeter_server.py 中,我修改了 SayHello() 方法:

# ...
def SayHello(self, request, context):
    print("Request arrived, sleeping a bit...")
    time.sleep(10)
    return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
# ...

serve() 方法:

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), maximum_concurrent_rpcs=2)
    # ...

然后我打开 3 个终端并在其中手动执行客户端(尽可能快地使用 python greeter_client.py:

正如预期的那样,对于前 2 个客户端,请求的处理立即开始(可以在服务器的输出中看到),因为有足够的线程可用,但是第 3 个客户端立即被拒绝(如预期的那样)StatusCode.RESOURCE_EXHAUSTED超出并发 RPC 限制!

现在要测试当没有足够的线程分配给 ThreadPoolExecutor 时会发生什么,我将 max_workers 修改为 1:

server = grpc.server(futures.ThreadPoolExecutor(max_workers=1), maximum_concurrent_rpcs=2)

我在与之前大致相同的时间再次运行我的 3 个客户端。

结果是第一个立即得到服务。第二个需要等待 10 秒(当第一个被送达时)然后它被送达。第三个立即被拒绝。

关于python - gRPC Python thread_pool 与 max_concurrent_rpcs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51089746/

相关文章:

python - CancelledError : [_Derived_]RecvAsync is cancelled. 在 google colab 上运行

python - python中的多处理空间核密度估计

python - 在python中调整适合图像的大小

python map函数迭代

go - GRPC 消息结构

c# - 具有未加密 HTTP2 连接的 .Net Core 3.1 gRPC 客户端

ios - xcode9中grpc报错GPR_UNREACHABLE_COD如何修正

multithreading - 在 FutureTask 中包装 Callable/Runnable 有什么好处?

python - 如何在concurrent.futures.ThreadPoolExecutor中使用锁而不导致死锁?

java - 在 Java 中,当我们从正在执行 Future 线程的函数返回时会发生什么?