一、FastAPI 的核心架构概览
┌─────────────────────────────────┐│ FastAPI │├─────────────────────────────────┤│ ┌─────────────┐ ┌───────────┐ ││ │ Starlette │ │ Pydantic │ ││ │ (ASGI核心) │ │ (数据验证)│ ││ └─────────────┘ └───────────┘ │└─────────────────────────────────┘
FastAPI 的核心构建在两大支柱之上:
• Starlette:负责 ASGI 服务器、路由、中间件
• Pydantic:负责数据验证和序列化
二、依赖注入:FastAPI 的灵魂
2.1 什么是依赖注入
依赖注入是一种设计模式,通过将依赖项作为参数传递给函数,而不是在函数内部创建它们,从而降低代码耦合度。
2.2 FastAPI 的依赖注入实现
FastAPI 的依赖注入系统位于 fastapi/dependencies/utils.py:
def get_dependant(*,path: str,call: Callable[..., Any],name: str = None,security_scopes: List[str] = None,) -> Dependant:"""解析函数的依赖项"""path_params = get_path_param_names_from_callable(call)dependant = Dependant(path=path, call=call, name=name)# 获取路径参数、查询参数、请求体等for param_name, param in get_typed_signature(call).parameters.items():if param_name in path_params:add_param_to_fields(path_params, param_name, param, dependant.path_params)else:# 处理依赖项process_param(param, dependant)return dependant
2.3 依赖注入的执行流程
当请求到达时,FastAPI 会按以下顺序执行依赖注入:
1. 解析路由函数的签名↓2. 收集所有依赖项(包括嵌套依赖)↓3. 按依赖顺序解析每个依赖项↓4. 缓存已解析的依赖项↓5. 将解析后的值注入到路由函数
2.4 依赖注入的性能优化
FastAPI 在依赖注入中实现了多个性能优化:
1. 依赖缓存
class CacheKey:def __init__(self, obj: Any):self.obj = objdef __hash__(self):return id(self.obj)def __eq__(self, other):return self.obj is other.obj# 使用缓存避免重复解析cache: Dict[CacheKey, Any] = {}
2. 懒加载
依赖项只有在真正需要时才会被解析,而不是在应用启动时就全部初始化。
3. 并行解析
对于相互独立的依赖项,FastAPI 可以并行解析,充分利用异步特性。
三、请求处理流程:从 ASGI 到响应
3.1 ASGI 协议基础
ASGI (Asynchronous Server Gateway Interface) 是 Python 异步 Web 框架的标准接口。FastAPI 完全兼容 ASGI 协议。
ASGI 应用是一个接受两个参数的异步函数:
async def app(scope: dict,receive: Callable,send: Callable) -> None:...
3.2 FastAPI 的请求处理流程
async def __call__(self, scope: dict, receive: Callable, send: Callable) -> None:"""FastAPI 的 ASGI 入口点"""if scope["type"] == "lifespan":# 处理生命周期事件(启动/关闭)await self.router.lifespan_context(scope, receive, send)elif scope["type"] == "http":# 处理 HTTP 请求await self.router(scope, receive, send)elif scope["type"] == "websocket":# 处理 WebSocket 连接await self.router(scope, receive, send)
3.3 路由匹配机制
FastAPI 使用 Trie 树结构进行高效路由匹配:
class Router:def __init__(self):self.routes = [] # 路由列表self.routes_map = {} # 路由映射async def __call__(self, scope: dict, receive: Callable, send: Callable):# 1. 匹配路由route, path_params = self.match_route(scope["path"])# 2. 解析依赖项dependant = self.get_dependant(route)values = await self.solve_dependencies(dependant=dependant,request=Request(scope, receive))# 3. 调用路由函数result = await route.endpoint(**values)# 4. 返回响应response = self.get_response(result)await response(scope, receive, send)
四、中间件机制:拦截与增强
4.1 中间件的设计模式
FastAPI 的中间件基于 责任链模式,每个中间件可以:
• 修改请求对象
• 修改响应对象
• 短路请求(不继续处理)
Request → [中间件1] → [中间件2] → [路由处理] → [中间件2] → [中间件1] → Response4.2 中间件的实现
class Middleware:def __init__(self, app: ASGIApp):self.app = appasync def __call__(self, scope: dict, receive: Callable, send: Callable) -> None:if scope["type"] != "http":await self.app(scope, receive, send)return# 处理请求async def send_wrapper(message: Message) -> None:# 处理响应await send(message)await self.app(scope, receive, send_wrapper)
4.3 内置中间件
FastAPI 提供了多个内置中间件:
1. CORSMiddleware
处理跨域资源共享。
1. GZipMiddleware
自动压缩响应内容。
1. HTTPSRedirectMiddleware
自动将 HTTP 重定向到 HTTPS。
1. TrustedHostMiddleware
验证请求的主机头。
4.4 自定义中间件示例
from fastapi import FastAPI, Requestimport timeapp = FastAPI()@app.middleware("http")async def timing_middleware(request: Request, call_next):start_time = time.time()response = await call_next(request)process_time = time.time() - start_timeresponse.headers["X-Process-Time"] = str(process_time)return response
五、性能优化:为什么 FastAPI 这么快?

FastAPI 高性能特性
5.1 异步 I/O
FastAPI 充分利用 Python 的 asyncio 库,实现了真正的非阻塞 I/O:
# 同步方式(阻塞)def sync_read_file():with open("large_file.txt") as f:return f.read()# 异步方式(非阻塞)async def async_read_file():import aiofilesasync with aiofiles.open("large_file.txt") as f:return await f.read()
5.2 类型提示与代码生成
FastAPI 利用 Python 的类型提示,在运行时自动生成:
• OpenAPI 文档
• 请求验证逻辑
• 响应序列化逻辑
这些逻辑在应用启动时就被预编译,避免了运行时的反射开销。
5.3 Pydantic 的底层优化
Pydantic 使用 Rust 实现核心逻辑,将数据验证性能提升了一个数量级:
# Python 实现(较慢)def validate_int(value):if not isinstance(value, int):raise ValueError("Must be an integer")return value# Rust 实现(更快)# pydantic 内部使用 Rust 实现
5.4 路由查找优化
FastAPI 使用 Trie 树进行路由匹配,时间复杂度为 O(k),其中 k 是 URL 路径的长度:
# Trie 树结构class TrieNode:def __init__(self):self.children = {}self.handler = None# 路由查找def find_route(self, path: str) -> Tuple[Callable, Dict]:node = self.rootparams = {}for segment in path.split("/"):if segment in node.children:node = node.children[segment]else:# 处理动态参数if "*" in node.children:node = node.children["*"]params["path"] = segmentreturn node.handler, params
六、实战案例:构建一个高性能 API
让我们用学到的知识构建一个简单的用户管理 API:
from fastapi import FastAPI, Depends, HTTPException, statusfrom typing import Optional, Listfrom pydantic import BaseModel, EmailStrimport timeapp = FastAPI()# 数据模型class User(BaseModel):id: intname: stremail: EmailStrage: Optional[int] = Noneclass UserCreate(BaseModel):name: stremail: EmailStrage: Optional[int] = None# 内存数据库users_db = {1: User(id=1, name="张三", email="zhangsan@example.com", age=30)}next_user_id = 2# 依赖项async def get_user(user_id: int) -> User:if user_id not in users_db:raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,detail="用户不存在")return users_db[user_id]# 中间件@app.middleware("http")async def timing_middleware(request, call_next):start = time.time()response = await call_next(request)process_time = time.time() - startresponse.headers["X-Process-Time"] = f"{process_time:.3f}s"return response# 路由@app.get("/users", response_model=List[User])async def list_users():return list(users_db.values())@app.get("/users/{user_id}", response_model=User)async def get_user_endpoint(user: User = Depends(get_user)):return user@app.post("/users", response_model=User, status_code=status.HTTP_201_CREATED)async def create_user(user_data: UserCreate):global next_user_iduser = User(id=next_user_id, **user_data.dict())users_db[next_user_id] = usernext_user_id += 1return user@app.put("/users/{user_id}", response_model=User)async def update_user(user_data: UserCreate,user: User = Depends(get_user)):user.name = user_data.nameuser.email = user_data.emailuser.age = user_data.agereturn user@app.delete("/users/{user_id}", status_code=status.HTTP_204_NO_CONTENT)async def delete_user(user: User = Depends(get_user)):users_db.pop(user.id)return None
七、性能测试与对比
7.1 测试方法论
GET /users | |
可重复性验证:三轮运行 RPS 变异系数 CV 均在 1.95% ~ 4.15% 范围内(< 5%),数据可信度高。
7.2 吞吐量对比(核心结论)
| Starlette | 12,080 | 3.25× | 3.56× | ||
| FastAPI | 10,293 | 2.77× | 3.03× | ||

关键发现:
FastAPI 吞吐量为 Flask 的 2.77 倍、Django 的 3.03 倍
在同等硬件和压测条件下,FastAPI 处理能力显著优于传统同步框架 Starlette 作为底层引擎领先约 17%
Starlette: 12,080 RPS → FastAPI: 10,293 RPS 差异来自 FastAPI 在 Starlette 之上增加的依赖注入、请求校验、路由解析等抽象层开销 Flask 与 Django 性能接近
Flask (3,715) 仅略高于 Django (3,397) 两者均为同步 WSGI 模式,受 GIL 和阻塞模型制约
7.3 延迟分位数分析
| Starlette | 7.78 | 8.90 | 11.24 | 16.88 | 2.17 |
| FastAPI | 9.14 | 10.70 | 12.93 | 19.44 | 2.13 |

关键发现:
FastAPI 的 P99 延迟仍优于 Flask/Django 的 P50 延迟
FastAPI P99 = 19.44ms < Flask P50 = 26.40ms(快 26.4%) FastAPI P99 = 19.44ms < Django P50 = 28.47ms(快 31.7%) - 这是最震撼的对比:
即使拿 FastAPI 的"最坏情况",依然比传统框架的"典型情况"更快 异步框架的尾延迟比更高但绝对值更优
Starlette/FastAPI 的 P99/P50 ≈ 2.1-2.2(分布略宽) Flask/Django 的 P99/P50 ≈ 1.3(分布窄) 但异步框架的绝对延迟值远低于同步框架,尾延迟比高仅因基数极小 P95 延迟差异体现稳定性
FastAPI P95 = 12.93ms(95% 的请求在此时间内完成) Flask P95 = 29.83ms(是 FastAPI 的 2.31 倍)
7.4 FastAPI 设计哲学:「抽象税」分析
FastAPI 建立在 Starlette 之上,其额外抽象层带来的性能代价量化如下:
| 吞吐量损失 | -14.8% | |
| 吞吐量比值 | 0.852 | |
| +1.45ms (+17.5%) | ||
| +15.1% | ||
| +2.69ms (+16.1%) |

核心结论:FastAPI 以 ~15% 的吞吐量代价 换取了:
✅ 自动请求校验(Pydantic) ✅ 依赖注入系统 ✅ OpenAPI 文档自动生成 ✅ 类型安全的路由与响应模型 这是一次极具性价比的工程权衡——用不到 3ms 的绝对延迟增长换取完整的开发体验升级。
7.5 三次运行稳定性验证

- 所有框架 CV 均 < 5%,满足工业级基准测试标准
FastAPI 波动稍大 (4.15%) 可能与 uvicorn 异步调度抖动有关,但不影响结论有效性 Django 最稳定 (CV 1.95%),因其同步模型行为确定性最高
7.6 测试结论
1. FastAPI 的性能优势不是「玄学」,而是架构选择的结果——ASGI + asyncio 让单进程吞吐量达到同步框架的近 3 倍。
2. FastAPI 在 Starlette 之上的抽象开销仅 ~15%,证明其依赖注入和校验系统的实现是高效的,而非臃肿的装饰层。
3. 最直观的对比是 FastAPI 的 P99 < Flask 的 P50——即使在最坏情况下,异步框架的延迟表现也优于同步框架的典型情况。
八、最佳实践与建议
8.1 依赖注入的最佳实践
✅ 推荐做法
# 使用 Class-based 依赖class Database:def __init__(self):self.conn = create_connection()async def close(self):await self.conn.close()db = Database()@app.on_event("shutdown")async def shutdown_event():await db.close()
❌ 避免做法
# 每次请求都创建新连接def get_db():return create_connection() # 性能浪费
8.2 中间件的顺序
中间件的执行顺序非常重要:
# 正确顺序:CORS → GZip → 自定义app.add_middleware(CORSMiddleware, ...)app.add_middleware(GZipMiddleware, ...)app.add_middleware(CustomMiddleware, ...)
8.3 避免同步阻塞
❌ 错误:在异步函数中使用同步 I/O
@app.get("/data")async def get_data():data = open("file.txt").read() # 阻塞!return {"data": data}
✅ 正确:使用异步 I/O
@app.get("/data")async def get_data():import aiofilesasync with aiofiles.open("file.txt") as f:data = await f.read() # 非阻塞return {"data": data}
九、总结
FastAPI 的高性能来自多个层面的精心设计:
• 异步架构:基于 ASGI 和 asyncio,充分利用异步 I/O
• 依赖注入:优雅的设计模式,降低耦合,提高可测试性
• 类型提示:自动生成文档和验证逻辑,减少运行时开销
• 中间件系统:灵活的责任链模式,便于功能扩展
• 底层优化:Pydantic 使用 Rust 实现核心逻辑
通过理解这些核心机制,我们不仅能更好地使用 FastAPI,还能在需要时进行针对性的性能优化。
今天的内容就到这里,感谢你看到最后
琴萧双手奉上一份Python大礼包(总共155G),涵盖爬虫、web开发、数据分析、机器学习、人工智能等等的学习资料
点击下方卡片,发送20260626即可领取
夜雨聆风