0

0

Python如何写中间件_拦截请求与计算API响应时间示例

P粉602998670

P粉602998670

发布时间:2026-03-10 19:13:02

|

266人浏览过

|

来源于php中文网

原创

必须在await call_next(request)前用time.time()存入request.state.start_time,之后用time.time()-request.state.start_time计算耗时,取整毫秒输出;response.status_code可用,body不可读;须用basehttpmiddleware确保覆盖所有请求。

python如何写中间件_拦截请求与计算api响应时间示例

FastAPI中间件里怎么拿到请求开始时间

关键不是“存时间”,而是得在请求刚进来、还没进路由前就记下那一刻。用 time.time() 最直接,但别存在局部变量里——中间件函数执行完就丢了,得挂到 request.state 上才能传给后续逻辑。

常见错误是写成全局变量或模块级变量存时间,结果并发请求互相覆盖;或者用 datetime.now() 但没注意时区和精度,导致响应时间算出来负数或偏差大。

  • 必须在 await call_next(request) 前调用 time.time()
  • 务必存到 request.state.start_time = time.time(),不能存到普通变量
  • 避免用 datetime.utcnow(),它不保证单调递增,高并发下可能倒退

如何在FastAPI中间件里安全读取响应体并计算耗时

不能直接读 response.body,因为 FastAPI 的 Response 对象默认 body 是惰性生成的,且可能被流式处理(比如 StreamingResponse)。真要测耗时,只关心“从收到请求到返回 headers 的时间”,也就是 call_next() 返回的时刻减去开始时间即可。

想额外记录状态码或路径?可以从 response.status_coderequest.url.path 拿,这两个字段在 call_next() 返回后就稳定可用。

立即学习Python免费学习笔记(深入)”;

秘塔回响
秘塔回响

秘塔AI语音输入法

下载
  • 耗时 = time.time() - request.state.start_time,放在 await call_next(request) 后立刻算
  • response.status_code 可靠,但 response.body 多数情况是 b'' 或不可读,别碰
  • 如果用了 BackgroundTasks 或异步写日志,确保不阻塞主响应流程

为什么用 Starlette 的 BaseHTTPMiddleware 而不是装饰器写法

装饰器方式(比如给每个路由加 @timing)看着简单,但漏掉所有 404、422、CORS 预检请求,也抓不到异常响应(比如未捕获的 HTTPException)。而中间件走的是 ASGI 生命周期底层,所有进入应用的请求都过一遍。

Starlette 的 BaseHTTPMiddleware 是 FastAPI 官方推荐基类,它自动处理了 request/response 的 scope 生命周期,比手写 ASGI callable 更稳;自己写 async def middleware(request, call_next): 也能用,但容易漏掉异常传播逻辑。

  • BaseHTTPMiddleware 子类,重写 dispatch 方法,结构清晰不易错
  • 别用 @app.middleware("http") 装饰器配合手动 try/except 包裹 call_next,异常时 response 可能为空
  • 如果项目用了 HTTPSRedirectMiddlewareTrustedHostMiddleware,你的耗时中间件得排在它们之后才合理

日志里打印响应时间要不要带单位和小数位

要。不带单位就是裸数字,后期查问题时根本分不清是毫秒还是秒;小数位太多(比如保留 6 位)反而干扰判断,因为网络栈本身就有微秒级抖动,Python 的 time.time() 在 Linux 上通常只有 10ms 级精度。

实际线上建议统一用毫秒、整数,既对齐监控系统(如 Prometheus 的 _seconds 指标),又避免浮点误差。如果做 APM 追踪,再考虑纳秒级 time.perf_counter_ns(),但中间件里没必要。

  • 输出格式推荐:f"status={response.status_code} path={request.url.path} time_ms={int((end - start) * 1000)}"
  • 别用 round(..., 3) 再转字符串,浮点舍入可能引入不可预期的 0.001 差异
  • 如果日志量大,避免在中间件里做字符串拼接,先存数字,交由日志库格式化

事情说清了就结束。中间件看似简单,但时间戳的采集时机、response 字段的可用性边界、以及 ASGI 中间件链的执行顺序,三者稍一错位,统计出来的“响应时间”就完全失真。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
什么是中间件
什么是中间件

中间件是一种软件组件,充当不兼容组件之间的桥梁,提供额外服务,例如集成异构系统、提供常用服务、提高应用程序性能,以及简化应用程序开发。想了解更多中间件的相关内容,可以阅读本专题下面的文章。

182

2024.05.11

Golang 中间件开发与微服务架构
Golang 中间件开发与微服务架构

本专题系统讲解 Golang 在微服务架构中的中间件开发,包括日志处理、限流与熔断、认证与授权、服务监控、API 网关设计等常见中间件功能的实现。通过实战项目,帮助开发者理解如何使用 Go 编写高效、可扩展的中间件组件,并在微服务环境中进行灵活部署与管理。

226

2025.12.18

Python FastAPI异步API开发_Python怎么用FastAPI构建异步API
Python FastAPI异步API开发_Python怎么用FastAPI构建异步API

Python FastAPI 异步开发利用 async/await 关键字,通过定义异步视图函数、使用异步数据库库 (如 databases)、异步 HTTP 客户端 (如 httpx),并结合后台任务队列(如 Celery)和异步依赖项,实现高效的 I/O 密集型 API,显著提升吞吐量和响应速度,尤其适用于处理数据库查询、网络请求等耗时操作,无需阻塞主线程。

28

2025.12.22

Python 微服务架构与 FastAPI 框架
Python 微服务架构与 FastAPI 框架

本专题系统讲解 Python 微服务架构设计与 FastAPI 框架应用,涵盖 FastAPI 的快速开发、路由与依赖注入、数据模型验证、API 文档自动生成、OAuth2 与 JWT 身份验证、异步支持、部署与扩展等。通过实际案例,帮助学习者掌握 使用 FastAPI 构建高效、可扩展的微服务应用,提高服务响应速度与系统可维护性。

251

2026.02.06

Python FastAPI异步API开发_Python怎么用FastAPI构建异步API
Python FastAPI异步API开发_Python怎么用FastAPI构建异步API

Python FastAPI 异步开发利用 async/await 关键字,通过定义异步视图函数、使用异步数据库库 (如 databases)、异步 HTTP 客户端 (如 httpx),并结合后台任务队列(如 Celery)和异步依赖项,实现高效的 I/O 密集型 API,显著提升吞吐量和响应速度,尤其适用于处理数据库查询、网络请求等耗时操作,无需阻塞主线程。

28

2025.12.22

Python 微服务架构与 FastAPI 框架
Python 微服务架构与 FastAPI 框架

本专题系统讲解 Python 微服务架构设计与 FastAPI 框架应用,涵盖 FastAPI 的快速开发、路由与依赖注入、数据模型验证、API 文档自动生成、OAuth2 与 JWT 身份验证、异步支持、部署与扩展等。通过实际案例,帮助学习者掌握 使用 FastAPI 构建高效、可扩展的微服务应用,提高服务响应速度与系统可维护性。

251

2026.02.06

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

93

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

106

2025.09.18

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

4

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 4.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号