首页 > 其他分享 >关于FastAPI异步并发的技术背景和细节

关于FastAPI异步并发的技术背景和细节

时间:2022-11-15 22:22:09浏览次数:70  
标签:异步 FastAPI await 并发 async def

FastAPI的路径操作函数,可以使用async def定义:

from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}

这算得上是FastAPI的典型特征之一。

关于这个框架设计,有哪些技术背景和细节呢?

技术背景

在Python语法里面,如果你想异步请求三方库,需要使用await:

results = await some_library()

使用了await就必须在def前面加上async:

@app.get('/')
async def read_results():
    results = await some_library()
    return results

这是Python语法规定。

FastAPI并不要求所有的路径操作函数,都必须定义为async,假如你要实时访问某些三方库,可以简单的使用def就行,不用加上await:

@app.get('/')
def results():
    results = some_library()
    return results

但是无论你是否使用async,FastAPI都将异步工作,以达到"Fast"的运行速度。

看完文章就明白这句话的意思了。

技术细节

Python新版本已经原生支持异步代码了。所谓异步代码,指的是编程语言,会告诉计算机程序,在某个时刻停下来,等待其他任务完成后,再继续运行。在等待期间,计算机程序可以去干点别的事情,而不用一直卡在那里。这些“其他任务”,通常指的是耗时较长的IO操作,比如:

  • 客户端通过网络发送数据;

  • 服务端通过网络发送数据;

  • 程序从磁盘读取文件内容;

  • 程序将文件内容写入磁盘;

  • 远程API操作;

  • 数据库操作;

  • 数据库查询返回结果;

这些操作主要阻塞在IO等待,所以又叫做IO密集型。

并发和并行

异步有时候也叫做并发。并发(Concurrency)和并行(parallelism)是不同的概念,并发是指一个处理器同时处理多个任务,并行是指多个处理器同时处理多个不同的任务,并发是逻辑上的同时发生,并行是物理上的同时发生。

并发

餐厅有1个服务员和1个厨子。

你带女朋友到餐厅排队点汉堡:

你们给服务员说来2个汉堡:

服务员给厨师说做2个汉堡:

然后给了你们一个排号:

你们开心的等,因为有排号,不需要担心别人会抢走:

叫号了:

取了汉堡高高兴兴的吃:

并行

餐厅有5个服务员兼厨子。

你们看哪个窗口有空位:

到餐台点2个汉堡:

服务员自己跑到厨房做汉堡:

你们只能站在原地等,如果走开,可能会被其他人拿走:

汉堡做好了:

你的女朋友不开心:

从这个买汉堡的漫画中,可以看到并行比并发会做更多无意义的等待,并行需要5个人(5个服务员兼厨子),并发只需要2个人(1个服务员1个厨子)。这就是为什么很多Web框架要设计成异步并发了,因为很多客户端会发请求给服务端,然后服务端响应给客户端,如果有太多无用的等待,那么整个应用将慢得无法使用。而且硬件资源有限,并发也能更高效利用资源,节约成本。

并发一定就比并行好吗?也不是,只有在出现很多等待时,并发才比并行好。比如你们要打扫房间,一间一间的打扫,没有等待,那么并发和并行就没有区别,如果你再叫3个朋友一起打扫,并行就能更快打扫完。这种执行时间完全取决于任务本身而不是等待的情况,又叫做CPU密集型。计算机里的CPU密集型操作通常需要更复杂的数据计算,比如:

  • 音频或图片处理;

  • 计算机视觉;

  • 机器学习;

  • 深度学习;

FastAPI既支持异步并发,也支持多线程并行。

async和await

异步并发使用async和await来实现。

async定义函数:

async def get_burgers(number: int):
    # Do some asynchronous stuff to create the burgers
    return burgers

await调用函数:

@app.get('/burgers')
async def read_burgers():
    burgers = await get_burgers(2)
    return burgers

细节中的细节

FastAPI会对路径操作函数(path operation function)和依赖(dependencies)进行特殊处理。这个特殊处理是:如果你把函数定义为def而不是async def,那么FastAPI会把它放到单独的线程池中,异步执行,这就是FastAPI精彩的地方。就像官方所说,如果你不清楚你函数里面的调用是不是异步(能不能用await),那么就把它定义为普通函数,FastAPI会采用多线程的方式处理。乱用async,在async里面有同步调用,则会变成串行,Fast秒变Slow。

而对于其他函数,FastAPI则不会管,def就是同步调用,立马返回结果。

现在回过头来看前面的那句话:但是无论你是否使用async,FastAPI都将异步工作,以达到"Fast"的运行速度。应该更加明白了。

参考资料:

Concurrency and async / await - FastAPI https://fastapi.tiangolo.com/async/

很火的Fastapi框架,用async函数真的比普通函数快吗?https://blog.csdn.net/yyw794/article/details/108859240

标签:异步,FastAPI,await,并发,async,def
From: https://www.cnblogs.com/df888/p/16890685.html

相关文章

  • 服务异步通信-高级篇
    服务异步通信-高级篇消息队列在使用过程中,面临着很多实际问题需要思考:1.消息可靠性消息从发送,到消费者接收,会经理多个过程:其中的每一步都可能导致消息丢失,常见的丢失......
  • js闭包问题、js事件循环机制、async与defer、同步与异步模式
    js闭包问题定义:闭包就是有权访问其他函数作用域内的其他变量的函数。实现机制:在访问变量的函数中return一个匿名函数,这时匿名函数的作用域链将指向该函数的作用域。!!!由于......
  • 040_并发下集合类不安全
    目录并发下ArrayList不安全解决方案一:Vector(不推荐使用)解决方案二:Collections.synchronizedList()解决方案三:CopyOnWriteArrayList(推荐使用)并发下HashSet不安全解决方......
  • 接口性能指标-QPS-TPS-并发量
    转载:https://www.cnblogs.com/liuqingzheng/p/16207660.html1QPSQueriesPerSecond,每秒查询率,一台服务器每秒能够响应的查询次数。是对一个特定的查询服务器在规定......
  • 并发上传md5值不匹配解决方法
    因为同步分片上传对于大文件非常耗时,如果并发上传定会出现乱序,而某些厂商的云盘没有对分片并发上传做相应处理,导致上传后的文件与原文件md5值不匹配。以下给出我对此问题......
  • 异步编排 Spring(线程池)
    目录异步编排CompletableFuture的详解代码测试配置类的引入Demo1Demo2CompletableFuture的async后缀函数与不带async的函数的区别ThreadPoolTaskExecutor和ThreadPoolEx......
  • 异步和多线程有什么区别
    一、异步和多线程有什么区别?其实,异步是目的,而多线程是实现这个目的的方法。 多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至......
  • 网络并发1
    今日内容总结软件开发架构规定了程序的请求逻辑、功能模块1.C/S架构 Client:客户端 Server:服务端"""我们使用计算机下载下来的一个个app本质是各大互联网公司的客......
  • websocket 进阶!netty框架实现websocket达到高并发
    引言:在前面两篇文章中,我们对原生websocket进行了了解,且用demo来简单的讲解了其用法。但是在实际项目中,那样的用法是不可取的,理由是tomcat对高并发的支持不怎么好,特别是tomca......
  • 异步pyppeteer:并发运行多个浏览器并收集结果
    网上代码一大抄,居然网上讲pyppeteer异步的一大推,但运行起来都是await,并没有讲如何同时并发运行十几二个pyppeteer页面,那有个卵用呀,还不如开个多进程呢。话不多说,上代码。......