python - python asyncio gRPC 客户端的多线程支持
问题描述
我有一个在多线程环境中使用的 asyncio gRPC 客户端。当多个线程同时通过客户端连接到服务时,我看到以下错误流:
2021-01-27 09:33:56,937 错误 [asyncio] [thread_0] 回调 PollerCompletionQueue._handle_events()() 中的异常 句柄:)()> 回溯(最近一次通话最后): _run 中的文件“/usr/local/lib/python3.8/asyncio/events.py”,第 81 行 self._context.run(self._callback, *self._args) 文件“src/python/grpcio/grpc/_cython/_cygrpc/aio/completion_queue.pyx.pxi”,第 147 行,在 grpc._cython.cygrpc.PollerCompletionQueue._handle_events BlockingIOError: [Errno 11] 资源暂时不可用 2021-01-27 09:33:56,937 错误 [asyncio] [thread_1] 回调 PollerCompletionQueue._handle_events()() 中的异常 句柄:)()> 回溯(最近一次通话最后): _run 中的文件“/usr/local/lib/python3.8/asyncio/events.py”,第 81 行 self._context.run(self._callback, *self._args) 文件“src/python/grpcio/grpc/_cython/_cygrpc/aio/completion_queue.pyx.pxi”,第 147 行,在 grpc._cython.cygrpc.PollerCompletionQueue._handle_events BlockingIOError: [Errno 11] 资源暂时不可用
请求似乎成功完成,但是,消息充斥着我的日志,让我紧张!
在我的测试中,每个线程都创建自己的通道并提交自己的异步请求。无论服务负载如何,都会发生错误。如果客户端在不同的进程中运行,则不会发生错误。
我的设置:
- 蟒蛇版本:
3.8.6
grpcio
版本:1.35.0
任何见解表示赞赏!
解决方案
gRPC AsyncIO 使用 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
推荐阅读
- c# - 如何在不丢失 CefSharp 浏览器的情况下最小化和最大化 WinForms 表单?
- filehelpers - FileHelpers 问题 - 如何在没有换行符或分隔符的情况下读取固定长度文件
- css - 如何在 .NET Framework 项目中禁用 SCSS 编译文件
- html5-canvas - Canvas 中奇怪的视图框字体大小调整行为
- c# - 在 Visual Studio 2019 中重新启用标题栏
- javascript - 如何使用 JavaScript 显示图像和文本搜索结果?
- java - Spring boot Jsp / Tag在不同模块中
- jquery - Jssor 是否可以在滑块上放置一个暂停按钮并播放?
- spring - Spring Boot 执行器端点未通过 HTTP 公开
- python - 将 Pandas DataFrame 列值与另一个 DataFrame 列匹配