我们组有个 python 服务,里面有一些机器学习的功能,例如人脸识别和 ocr 还有音频分析等。这些任务用到的通常都是阻塞性的 api。现在我是通过 twsited 将它们创建成单独的线程或进程。但是我更想结合最近实践到的 fastapi 和 lifespan 来管理。

但是 lifespan 启动后台任务比较适合做一些 io 密集的,如果是这种 cpu 的可以说是典型错误了。那么进一步说,到底如何让 CPU 密集和 IO 密集的代码在 async 中协同工作呢?

答案是使用 asyncio.run_in_executor.

这个方法可以将一些任务 offload 到线程或者进程,具体取决于你传入的 executor 是什么。返回值是一个 Future 所以你就可以把它无缝组合到自己的 async 代码中了!

我打算在 lifespan 中使用 asyncio.create_task 创建一系列 tasks 然后在 tasks 中涉及到 CPU 密集方法时使用 asyncio.run_in_executor 执行,这样可以保证主服务 fastapi 不受到影响。同时,我们可以对 executor 进行 max_worker 限制,通过一些手段感知容器或物理机中的 cpu 数量,这样 CPU 密集的任务可以充分地利用到多核

#架构设计思考
 
 
Back to Top