我有一个异步gRPC客户端,用于多线程环境。当多个线程通过客户端同时连接到服务时,我看到以下错误流:
2021-01-27 09:33:56,937 ERROR [asyncio] [thread_0] Exception in callback PollerCompletionQueue._handle_events()() handle: )()> Traceback (most recent call last): File "/usr/local/lib/python3.8/asyncio/events.py", line 81, in _run self._context.run(self._callback, *self._args) File "src/python/grpcio/grpc/_cython/_cygrpc/aio/completion_queue.pyx.pxi", line 147, in grpc._cython.cygrpc.PollerCompletionQueue._handle_events BlockingIOError: [Errno 11] Resource temporarily unavailable 2021-01-27 09:33:56,937 ERROR [asyncio] [thread_1] Exception in callback PollerCompletionQueue._handle_events()() handle: )()> Traceback (most recent call last): File "/usr/local/lib/python3.8/asyncio/events.py", line 81, in _run self._context.run(self._callback, *self._args) File "src/python/grpcio/grpc/_cython/_cygrpc/aio/completion_queue.pyx.pxi", line 147, in grpc._cython.cygrpc.PollerCompletionQueue._handle_events BlockingIOError: [Errno 11] Resource temporarily unavailable
请求似乎正在成功完成,但是,这些消息充斥着我的日志,让我感到紧张!
在我的测试中,每个线程创建自己的通道并提交自己的异步请求。无论服务负载如何,都会发生错误。如果客户端在不同的进程中运行,则不会发生错误。
我的设置:
3.8。6
grpcio
version:1.35。0
任何洞察都将不胜感激!
gRPC异步IO使用UDS在C扩展和Python之间进行通信。从您的日志中,存在fd访问的竞争条件。AsyncIO API支持多线程,但这似乎是一个新问题(它有助于在上创建问题)https://github.com/grpc/grpc/issues).
竞争条件的修复可能很棘手,因为AsyncIO使用的AsyncIO锁不是线程安全的。如果我们用线程安全锁保护fd,它可能会阻塞AsyncIO循环。随时提出或贡献解决方案。
如果让所有客户端在一个线程上运行,AsyncIO的性能最好。事件循环可以很好地处理协同路由的执行,而不需要线程跳转。如您所述,如果目标是饱和机器上的所有计算能力,那么最好使用多重处理。
链接到基本gRPC AsyncIO示例:https://github.com/grpc/grpc/blob/master/examples/python/helloworld/async_greeter_client.py