FastAPI 的依赖注入与生命周期管理深度解析

FastAPI 的依赖注入与生命周期管理深度解析

目录

  1. 🔧 依赖注入与 FastAPI 高级特性

    • 1.1 依赖注入的基础与核心概念
    • 1.2 FastAPI 的依赖注入机制与设计理念
    • 1.3 FastAPI 依赖注入的异步特性
  2. 🕹 生命周期与依赖的异步管理

    • 2.1 依赖的生命周期管理:数据库连接与缓存
    • 2.2 利用 FastAPI 的异步特性优化依赖注入性能
  3. 🌐 FastAPI 中的高效依赖管理与性能优化

    • 3.1 如何使用背景任务进行依赖管理
    • 3.2 依赖注入与多线程、多进程应用场景
  4. 🏗 实际项目中的依赖注入应用场景

    • 4.1 在微服务架构中使用 FastAPI 的依赖注入
    • 4.2 集成外部服务与第三方库的依赖管理

2. 🕹 生命周期与依赖的异步管理

2.1 依赖的生命周期管理:数据库连接与缓存

在 FastAPI 中,依赖注入(Dependency Injection)是一个强大的特性,允许开发者在 API 端点中自动管理和注入复杂的依赖。依赖注入不仅限于基本的功能,还可以帮助开发者更高效地管理资源的生命周期,尤其是在涉及数据库连接、缓存、外部服务等情况下。通过合理的生命周期管理,开发者能够确保系统资源的高效使用,避免重复创建和销毁资源的性能问题。

依赖注入的生命周期

FastAPI 提供了一种灵活的依赖管理方式,支持两种主要的生命周期管理方式:

  1. 请求级别依赖:每次请求创建新的依赖对象,适用于如数据库连接、用户认证等在每个请求中都有不同状态的依赖。
  2. 应用级别依赖:整个应用生命周期内共享的依赖,适用于如缓存实例、连接池等跨多个请求复用的资源。

在 FastAPI 中,开发者可以通过 Depends 来定义依赖。以下是一个数据库连接生命周期的例子,演示了如何管理数据库连接:

from fastapi import FastAPI, Depends
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from contextlib import contextmanager# 创建数据库引擎和会话
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)# 使用 contextmanager 管理会话的生命周期
@contextmanager
def get_db():db = SessionLocal()try:yield dbfinally:db.close()# 创建 FastAPI 应用
app = FastAPI()# 定义数据库依赖
def get_database(db: Session = Depends(get_db)):return db@app.get("/users/")
def read_users(db: Session = Depends(get_database)):# 使用 db 进行数据库操作return {"msg": "Fetching user data..."}

在上述代码中,get_db 函数利用 contextmanager 来管理数据库会话的生命周期。每次请求时,FastAPI 会自动调用 get_db 来创建一个新的数据库会话,并在请求结束后自动关闭该会话。这种方式确保了每个请求都能使用独立的数据库连接,并且避免了连接泄漏或过度占用数据库资源。

数据库连接池

对于高并发应用来说,创建和销毁数据库连接可能会成为性能瓶颈,因此数据库连接池通常会被用来重用现有的连接,从而提高应用的性能。FastAPI 与 SQLAlchemy 等库紧密集成,支持使用连接池。通过 SQLAlchemy 的连接池,开发者可以管理连接的复用和生命周期。

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker# 创建数据库引擎,使用连接池
SQLALCHEMY_DATABASE_URL = "postgresql://user:password@localhost/testdb"
engine = create_engine(SQLALCHEMY_DATABASE_URL, pool_size=10, max_overflow=20)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

在这个示例中,engine 配置了数据库连接池。pool_size 定义了池中保持的连接数,max_overflow 控制了池的最大溢出连接数。当请求到来时,FastAPI 会自动从连接池中获取一个连接,并在请求处理完成后将连接归还池中。

缓存管理

缓存是提升应用性能的另一个关键部分。在 FastAPI 中,依赖注入可以用于管理缓存生命周期。例如,可以使用 Redis 来缓存某些频繁访问的数据。以下代码展示了如何通过依赖注入管理 Redis 缓存的生命周期:

import redis
from fastapi import FastAPI, Dependsapp = FastAPI()# 创建 Redis 客户端
def get_cache():cache = redis.StrictRedis(host='localhost', port=6379, db=0)try:yield cachefinally:pass  # Redis 客户端通常无需显式关闭# 依赖注入 Redis 客户端
def get_cached_data(cache: redis.StrictRedis = Depends(get_cache)):return cache.get('some_key')@app.get("/cache/")
def read_cache(cached_data: bytes = Depends(get_cached_data)):return {"cached_data": cached_data.decode() if cached_data else "No data found"}

在此示例中,get_cache 函数通过依赖注入提供了 Redis 客户端。每次请求到来时,FastAPI 会自动提供一个新的 Redis 客户端实例。虽然在此简单示例中没有显式关闭 Redis 客户端,但在实际应用中,可以根据需要添加更多的资源清理逻辑。

2.2 利用 FastAPI 的异步特性优化依赖注入性能

FastAPI 具有对异步编程的良好支持,可以帮助开发者在 I/O 密集型应用中优化性能。通过异步的方式管理依赖的生命周期,可以显著提高应用的响应速度和吞吐量。尤其是在数据库访问、缓存操作或网络请求等场景中,异步能够最大化利用系统资源,提高并发处理能力。

异步数据库操作

FastAPI 的异步特性与数据库连接的异步操作相结合,可以帮助开发者优化数据库访问的性能。例如,使用 asyncpgdatabases 等库,FastAPI 可以在数据库查询时异步执行,避免阻塞主线程。

import databases
from fastapi import FastAPI, Depends# 创建数据库连接
DATABASE_URL = "postgresql://user:password@localhost/testdb"
database = databases.Database(DATABASE_URL)# 创建 FastAPI 应用
app = FastAPI()# 异步获取数据
async def get_data_from_db():query = "SELECT * FROM users"result = await database.fetch_all(query)return result@app.get("/users/")
async def read_users(data: list = Depends(get_data_from_db)):return {"users": data}

在这个例子中,get_data_from_db 函数通过异步方式访问数据库,避免了传统阻塞的 I/O 操作。database.fetch_all(query) 是异步执行的,这样在处理数据库查询时,FastAPI 可以处理更多的请求,提高系统的并发能力。

异步缓存操作

类似于数据库操作,FastAPI 也能够与异步缓存(如 Redis)结合,进行高效的缓存管理。例如,使用 aioredis 来管理 Redis 的异步操作,可以确保在高并发情况下依赖注入的性能得到最大化提升。

import aioredis
from fastapi import FastAPI, Dependsapp = FastAPI()# 异步创建 Redis 客户端
async def get_cache():cache = await aioredis.create_redis_pool('redis://localhost')return cache# 依赖注入 Redis 客户端
async def get_cached_data(cache: aioredis.Redis = Depends(get_cache)):cached_data = await cache.get('some_key')return cached_data@app.get("/cache/")
async def read_cache(cached_data: bytes = Depends(get_cached_data)):return {"cached_data": cached_data.decode() if cached_data else "No data found"}

在这个示例中,get_cacheget_cached_data 都是异步函数,它们能够高效地与 Redis 进行交互。通过使用异步缓存,系统可以处理更多的请求,避免了阻塞操作。

异步任务和背景任务

FastAPI 还支持背景任务,通过 BackgroundTasks 进行异步处理。对于需要长时间执行的任务(如数据处理、发送电子邮件等),可以将这些操作放入后台执行,避免阻塞主请求流程,提高用户体验。

from fastapi import FastAPI,BackgroundTasksapp = FastAPI()# 异步背景任务
def send_email(email: str):print(f"Sending email to {email}...")@app.post("/send-email/")
async def send_email_task(background_tasks: BackgroundTasks, email: str):background_tasks.add_task(send_email, email)return {"message": "Email sent in the background"}

在这个示例中,send_email 函数被添加到后台任务队列中执行,这样请求本身就不需要等待邮件发送完成,用户可以快速得到响应。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/503706.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

游戏引擎学习第77天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾昨天的 bug 今天我们继续开发进度,进行调试昨天代码的问题,主要是关于如何跟踪玩家和敌人在世界中的高度位置。虽然我们做的是一款 2D 游戏,但我们希望能够处理多层的房间,玩家…

【微服务】7、分布式事务

在分布系统中,一个业务由多个服务合作完成,每个服务有自己的事务,多个事务需同时成功或失败,这样的事务称为分布式事务。 其中每个服务的事务叫分支事务,整个业务的统一事务叫全局事务。 分布式事务相关知识讲解 课程引…

【pyqt】(四)Designer布局

布局 之前我们利用鼠标拖动的控件的时候,发现一些部件很难完成对齐这些工作,pyqt为我们提供的多种布局功能不仅可以让排版更加美观,还能够让界面自适应窗口大小的变化,使得布局美观合理。最常使用的三种布局就是垂直河子布局、水…

30天开发操作系统 第 12 天 -- 定时器

前言 定时器(Timer)对于操作系统非常重要。它在原理上却很简单,只是每隔一段时间(比如0.01秒)就发送一个中断信号给CPU。幸亏有了定时器,CPU才不用辛苦地去计量时间。……如果没有定时器会怎么样呢?让我们想象一下吧。 假如CPU看不到定时器而仍想计量时…

大数据-268 实时数仓 - ODS层 将 Kafka 中的维度表写入 DIM

点一下关注吧!!!非常感谢!!持续更新!!! Java篇开始了! MyBatis 更新完毕目前开始更新 Spring,一起深入浅出! 目前已经更新到了: H…

算法5--位运算

目录 基础经典例题[面试题 01.01. 判定字符是否唯一](https://leetcode.cn/problems/is-unique-lcci/description/)[268. 丢失的数字](https://leetcode.cn/problems/missing-number/description/)[371. 两整数之和](https://leetcode.cn/problems/sum-of-two-integers/descrip…

基于STM32设计的仓库环境监测与预警系统

目录 项目开发背景设计实现的功能项目硬件模块组成设计思路系统功能总结使用的模块的技术详情介绍总结 1. 项目开发背景 随着工业化和现代化的进程,尤其是在制造业、食品业、医药业等行业,仓库环境的监控和管理成为了至关重要的一环。尤其是在存储易腐…

代码随想录day38 动态规划6

题目:322.零钱兑换 279.完全平方数 139.单词拆分 多重背包 背包总结 需要重做:322,139 322. 零钱兑换 思路:零钱,可取多次-》完全背包。 注意: 五部: 1.dp[j]:价值为j的时候,最…

HackMyVM-Again靶机的测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、信息搜集 2、Getshell 3、提权 四、结论 一、测试环境 1、系统环境 渗透机:kali2021.1(192.168.101.127) 靶 机:Linux(192.168.101.204) 物理机:wi…

UDP_TCP

目录 1. 回顾端口号2. UDP协议2.1 理解报头2.2 UDP的特点2.3 UDP的缓冲区及注意事项 3. TCP协议3.1 报头3.2 流量控制2.3 数据发送模式3.4 捎带应答3.5 URG && 紧急指针3.6 PSH3.7 RES 1. 回顾端口号 在 TCP/IP 协议中,用 “源IP”, “源端口号”…

Android存储方案对比(SharedPreferences 、 MMKV 、 DataStore)

简介:本文介绍了Android开发中常用的键值对存储方案,包括SharedPreferences、MMKV和DataStore,并且对比了它们在性能、并发处理、易用性和稳定性上的特点。通过实际代码示例,帮助开发者根据项目需求选择最适合的存储方案&#xff…

Unity-Mirror网络框架-从入门到精通 总目录

前言 在现代游戏开发中,网络功能日益成为提升游戏体验的关键组成部分。本系列文章将为读者提供对Mirror网络框架的深入了解,涵盖从基础到高级的多个主题。Mirror是一个用于Unity的开源网络框架,专为多人游戏开发设计,它使得开发者…

element输入框及表单元素自定义前缀

如图所示&#xff1a; <el-input class"custom-input" placeholder"请输入" prefix-icon"prefix" v-model"form.name" clearable></el-input> :deep(.custom-input) {.el-input__icon {display: inline-block;width: 40…

现代谱估计的原理及MATLAB仿真(二)(AR模型法、MVDR法、MUSIC法)

现代谱估计的原理及MATLAB仿真AR参数模型法&#xff08;参数模型功率谱估计&#xff09;、MVDR法&#xff08;最小方差无失真响应法&#xff09;、MUSIC法&#xff08;多重信号分类法&#xff09; 文章目录 前言一、AR参数模型1 原理2 MATLAB仿真 二、MVDR法1 原理2 MATLAB仿真…

对话|全年HUD前装将超330万台,疆程技术瞄准人机交互“第一屏”

2024年&#xff0c;在高阶智驾进入快速上车的同时&#xff0c;座舱人机交互也在迎来新的增长点。Chat GPT、AR-HUD、车载投影等新配置都在带来新增量机会。 高工智能汽车研究院监测数据显示&#xff0c;2024年1-10月&#xff0c;中国市场&#xff08;不含进出口&#xff09;乘用…

LabVIEW之树形控件

一、树形控件基本构成 树形控件这个名称非常形象&#xff0c;其如同树一样&#xff0c;是典型的分层结构。树形控件的属性和方法使用非常灵活&#xff0c;树形控件的内容既可以静态编辑&#xff0c;也可以通过编程来动态填充。静态编辑树形控件适用于内容不变的应用场景&#…

springboot 集成 etcd

springboot 集成 etcd 往期内容 ETCD 简介docker部署ETCD 前言 好久不见各位小伙伴们&#xff0c;上两期内容中&#xff0c;我们对于分布式kv存储中间件有了简单的认识&#xff0c;完成了docker-compose 部署etcd集群以及可视化工具 etcd Keeper&#xff0c;既然有了认识&a…

gateway的路径匹配介绍

gateway是一个单独服务。通过网关端口和predicates进行匹配服务 1先看配置。看我注解你就明白了。其实就是/order/**配置机制直接匹配到orderservice服务。 2我试着请求一个路径&#xff0c;请求成功。下面第三步是请求的接口。 3接口。

嵌入式中QT实现文本与线程控制方法

第一:利用QT进行文件读写实现 利用QT进行读写文本的时候进行读写,读取MP3歌词的文本,对这个文件进行读写操作。 实例代码,利用Qfile,对文件进行读写。 //读取对应文件文件,头文件的实现。 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #incl…

书籍推荐:Kubernetes 修炼手册

这本书是 2020 年出版的&#xff0c;比较新&#xff0c;从 0 到 1 介绍了 k8s 中的相关技术和概念&#xff0c;翻译质量也可以&#xff0c;适合作为初学 k8s 的课外书。 书中比较关键的就是中间那几个章节&#xff0c;基本掌握 k8s 中 Pod、svc、StatefulSet、ConfigMap、Volum…