关于FastAPI的异步

FastAPI异步性能优势

我们先探讨一下并发和并行:
相关资料可以查询FastAPI的异步文档:https://fastapi.tiangolo.com/zh/async/

并发

也许很多人和我一样认为并发是任务在同时进行,但是并发只是在宏观上是同时进行的,在微观上是顺序进行的,只不过是切换时间短了而已。所以并发是同一时间段多个任务交替穿插执行,而不是同时进行,可以说宏观看似同时,微观上是交替执行的。

并行

并行就是真正同一时刻多个任务在同时进行。注意,单核CPU只有并发,没有并行,多核CPU才能并行执行多个任务。

还有一个问题就是python的一个特点:

GIL全局解释器锁

python的GIL全局解释器锁是指python解释器在多线程环境下,只能有一个线程执行,其他线程只能等待,如果是IO密集型任务,因为网络请求,数据库操作,等待响应等是阻塞的,空闲时刻立即主动释放GIL锁,空闲线程抢占GIL锁,实现多线程并发,所以任务之间就是并发进行的,但是如果是CPU密集型任务,因为要持续计算,无法主动释放GIL锁,只能串行执行。其他语言是没有全局解释锁的,比如java,所以单进程多进程是可以并行进行的,可以将多个线程分配给多核CPU,python是无法做到的,如果要解决CPU密集型问题,只能开启多进程从而摆脱GIL锁。

在而在互联网中大部分高并发问题都是IO密集型(大部分时间在等待数据库连接,网络请求等),而不是CPU密集型(大部分时间在计算,AI推理,加密解密等)。

异步优势

回归正题,FastAPI原生支持异步,遇到数据库操作网络请求等阻塞操作可以直接切换到其他任务执行,高效应对超高并发场景,对于常见的IO密集型任务可以轻松应对。而python的其他后端框架,比如django,flask等,都是同步的,只能处理一个请求,其他请求只能等待,效率低。
对比java的异步编程,java的异步编程需要使用回调函数,或者线程池,或者线程等机制,实现异步操作,而FastAPI的异步编程直接在路由中使用async/await语法,实现异步操作,更方便(java的我并不太了解,这个只是查阅了相关资料)
FastAPI的IO密集型性能接近Go语言,但是由于GIL锁的存在,CPU密集型任务的性能会低于Go语言,可以开启多进程后,性能会有所提高。