← 回總覽

两个字符让 Django 接口快了 8 倍:一次险些翻车的线上性能排查实录

📅 2026-06-05 08:45 腾讯云开发者 软件编程 2 分鐘 1662 字 評分: 89
后端开发 Django 性能优化 Python Web 开发
📌 一句话摘要 本文记录了一次 Django 接口性能排查过程,从 ORM 优化入手,最终发现真正瓶颈是 StreamingHttpResponse 对字符串的逐字符迭代,仅用一对方括号将响应时间从 13.6 秒降至 1.7 秒。 📝 详细摘要 文章详细复盘了某直播业务监控系统接口 get_svr_info 的性能优化过程。该接口在外部模块扩容后出现严重抖动,返回全量数据时响应体约 7MB,耗时 13.6 秒。作者最初判断瓶颈是 Django ORM 的 model 对象构造与 dict 转换开销,将代码改为 values() 直出 dict 并裁剪字段,但仅获得 1.12 倍提升。随后尝

📌 一句话摘要

本文记录了一次 Django 接口性能排查过程,从 ORM 优化入手,最终发现真正瓶颈是 StreamingHttpResponse 对字符串的逐字符迭代,仅用一对方括号将响应时间从 13.6 秒降至 1.7 秒。

📝 详细摘要

文章详细复盘了某直播业务监控系统接口 get_svr_info 的性能优化过程。该接口在外部模块扩容后出现严重抖动,返回全量数据时响应体约 7MB,耗时 13.6 秒。作者最初判断瓶颈是 Django ORM 的 model 对象构造与 dict 转换开销,将代码改为 values() 直出 dict 并裁剪字段,但仅获得 1.12 倍提升。随后尝试 ujson 替换 json.dumps(1.23x)和 nginx gzip 压缩(反而更慢),均未解决根本问题。通过 TTFB 分析和本机回环测试,发现 TTFB 仅 1 秒而 Total 长达 13 秒,说明瓶颈不在数据生成而在数据输出。最终定位到真凶:StreamingHttpResponse(json.dumps(big_data)) 将完整字符串作为可迭代对象,导致 Django 逐字符输出约 700 万次。修复方案是将字符串包裹在列表中(或直接使用 HttpResponse),使输出变为一次完成。最终全量场景从 13.6 秒降至 1.7 秒,最大提升 8.21 倍。文章总结了 TTFB 作为性能排查关键指标的价值,以及老代码中「看起来没错」的隐藏陷阱。

💡 主要观点

- StreamingHttpResponse 接收字符串时会逐字符迭代,导致巨大性能开销。 Python 字符串是可迭代对象,StreamingHttpResponse(big_string) 会将 7MB JSON 拆成约 700 万个单字符 chunk 逐个输出,造成 12 秒的额外耗时。

TTFB 与 Total 的差值能快速定位瓶颈在数据输出而非数据处理。 TTFB 约 1 秒说明 SQL、ORM、JSON 序列化很快完成;Total 约 13 秒说明大量时间花在 body 传输上,指向输出链路问题。
经验判断需要数据验证,性能优化不能靠资历投票。 作者最初自信地认为 ORM 对象构造是最大瓶颈,但实测仅提升 1.12 倍;真正的大问题藏在看似正确的 StreamingHttpResponse 用法中。
老代码中「看起来没错」的写法往往是最危险的隐藏陷阱。 StreamingHttpResponse(json.dumps(result)) 不报错、返回正确、上线多年,甚至名字暗示已做流式优化,但实际是假流式,稳定地慢直到流量爆发。

💬 文章金句

- 在掌握数据之前就下结论,是最大的错误。

  • 这不是流式输出,这是把一个大字符串交给 Django,让 Django 按字符串的迭代规则逐字符输出。
  • 性能问题不能靠资历投票,也不能靠直觉结案。
  • 拍胸脯之前,先跑 curl -w。

📊 文章信息

AI 初评:89

来源:腾讯云开发者

作者:腾讯云开发者

分类:软件编程

语言:中文

阅读时间:24 分钟

字数:5779

标签: 后端开发, Django, 性能优化, Python, Web 开发

阅读完整文章

查看原文 → 發佈: 2026-06-05 08:45:00 收錄: 2026-06-05 18:00:10

🤖 問 AI

針對這篇文章提問,AI 會根據文章內容回答。按 Ctrl+Enter 送出。