关于fastapi框架的异步

本文探讨了FastAPI框架的异步支持特性及其优势。对比Django的多线程实现方式,FastAPI采用协程机制,能有效减少线程间的上下文切换损耗,提升IO密集型任务的处理效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用fastapi框架开发web项目

1、为什么要用fastapi?

一直以来博主都是一直使用Django进行开发的,最近公司开始使用fastapi进行小项目的开发
通过博主对fastapi文档的翻阅,发现fastapi最引人注意的就是他的异步支持。(当然最新版的django也已经支持异步请求)

2、什么是异步?

异步相对应的就是同步
同步就是多件事排队做
而异步就是多件事同时做

3、在django中是怎么实现异步的呢?

django采取的是多线程实现异步。
当一个线程在做耗时操作的时候进行线程间切换,给人一种多个线程在同时运行的感觉。(当然了,多核cpu确实是真正的多线程。)。
切换的同时不仅要重新获取GIL锁,还要重新加载和记住上下文,这些开销对服务的性能是有一定影响的

4、fastapi中的异步

4.1 简单介绍一下协程的概念

相信大家都听说过协程这个概念,
协程是在一个线程间进行用户级资源切换的概念
是不是很抽象?
我来解释一下:

首先我们要了解线程属于进程,而协程属于线程
写过爬虫的同学应该了解过yield关键字,他就可以简单的作为一个协程来用
他可以构造一个生成器,可能有些同学会把生成器和一个普通的可迭代对象混为一谈(例如列表)

但是这又跟协程有什么关系呢?
是这样的,当用户要取一个元素的时候,这个生成器相当于被激活了,相当于开始占用线程资源,生成一个元素,返回之后就让出线程资源,直到用户取下一个元素。

这就是协程的思想:它没有线程间切换时资源的消耗大,并且完全由用户控制

4.2 fastapi中的协程

fastapi由较为完善的异步处理方案(没有非常完善)
他的基本语法与flask较为相似(虽然博主只写过一点flask)
值得一提的是asgi异步网关协议,这个网关协议有完善的异步请求与websocket的支持。

他对async/await有很好的支持
对应的web服务器是Uvicorn
我们可以使用sqlalchemy进行异步数据库查询

其实一个web项目的性能瓶颈大部分还是在io方面(数据库查询,web请求,系统io)
例如有些数据库查询确实耗时,我们又不想让他阻塞当前线程,我们就可以使用异步数据库查询
fastapi会在你注明异步数据库查询的地方让出cpu资源,让他去处理别的东西(比如另一个请求)
然后当你的数据库查询结束返回之后,再次回到当初让出资源的地方,继续往下执行。

5、协程相较于线程的优势:

协程可以记住上下文,从而避免在线程间切换中针对上下文切换的资源消耗和关于GIL锁的资源消耗

6、协程的使用场景

我们可以把计算机的动作大致分成两种,一种是计算型,一种是io型,当一个任务是计算型的时候,就意味着cpu要一直运行,这个时候我们是没法让出cpu资源的,而当一个任务是io型的,就相当于cpu一直在休息,在等待,这个时候我们就可以让出cpu的占用,让他去处理别的任务
所以协程异步并不是所有场景都适用,他主要用于io场景

### FastAPI 框架中的异步编程指南与示例 FastAPI 是一个现代、快速(高性能)的Web框架,用于构建API,基于Python类型提示。该框架支持异步操作,这使得开发人员可以编写高效的非阻塞代码。 #### 使用 `async` 和 `await` 为了实现异步功能,在定义路径操作函数时应使用关键字 `async def` 来声明它们为协程(coroutine),并在调用其他异步方法时使用 `await` 关键字[^3]: ```python from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") async def read_item(item_id: int): await some_async_function() return {"item_id": item_id} ``` 这里假设存在名为 `some_async_function()` 的异步函数来模拟实际业务逻辑处理过程。 #### 异步数据库交互 当涉及到像读取或写入这样的I/O密集型任务时,推荐采用异步驱动的数据访问库,例如 Tortoise ORM 或 SQLAlchemy 2.0+ 版本。下面是一个简单的例子展示如何利用 Motor 进行 MongoDB 数据库查询: ```python from motor.motor_asyncio import AsyncIOMotorClient from pydantic import BaseModel class Item(BaseModel): name: str description: str | None = None client = AsyncIOMotorClient('mongodb://localhost:27017') db = client.test_database @app.post('/create-item/', response_model=Item) async def create_item(item: Item): result = await db.items.insert_one(item.dict()) created_item = await db.items.find_one({'_id': result.inserted_id}) return created_item ``` 此段代码展示了创建新文档并立即检索刚插入记录的过程。 #### 并发执行多个请求 有时可能希望并发运行几个独立的任务而不必等待每一个完成后再继续下一个;这时就可以借助 Python 内置模块 asyncio 提供的功能——gather() 函数来达到目的: ```python import asyncio async def fetch_data(url): # Simulate network delay with sleep. await asyncio.sleep(1) return {'data': f'Fetched from {url}'} @app.get('/fetch-multiple/') async def fetch_multiple(): urls = ['http://example.com', 'https://another-site.org'] results = await asyncio.gather(*[fetch_data(url) for url in urls]) return results ``` 上述实例中,两个不同的URL被同时抓取数据,并最终一起返回给客户端。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值