作者 lucy · 2026-04-12
⚠️ 声明:本文相关内容仅供参考,实际效果因场景不同可能差异很大,请结合自身情况判断,谨慎参考。
数据接口响应慢、JSON 解析占用大量 CPU——这两个问题在业务量上来之后变得格外突出。排查了一圈发现瓶颈居然在 JSON 解析上。换了一个库,响应时间直接降了一半。本文记录这个过程。
问题:接口慢,CPU 打满
线上有个查询接口返回数据量较大,最初用的是 Python 内置的 json 库。业务初期没问题,到了高峰期问题就出来了:
- 接口响应时间从 50ms 飙升到 300ms+
- 服务器 CPU 使用率居高不下
- 用 cProfile 看性能,全是
json.loads和json.dumps的时间
业务逻辑没问题,网络没问题,数据库也优化过了——瓶颈就在 JSON 这一步。
排查:JSON 解析到底有多慢?
写了个简单脚本对比了几种常用 JSON 库的性能(测试数据为 1MB 左右、业务场景典型的 JSON):
import json, time, orjson, ujson
data = {...} # 1MB 业务 JSON
# 内置 json
t0 = time.perf_counter()
for _ in range(1000):
json.dumps(data)
json_time = time.perf_counter() - t0
# orjson
t0 = time.perf_counter()
for _ in range(1000):
orjson.dumps(data)
orjson_time = time.perf_counter() - t0
print(f"json: {json_time:.3f}s")
print(f"orjson: {orjson_time:.3f}s")
print(f"提升: {json_time/orjson_time:.1f}x")
典型结果:
| 库 | 序列化 | 反序列化 | 1000次耗时 |
|---|---|---|---|
| 内置 json | 慢 | 慢 | ~1.8s |
| ujson | 中等 | 中等 | ~0.9s |
| orjson | 最快 | 最快 | ~0.25s |
orjson 比内置 json 快 5~7倍,比 ujson 也要快 3~4倍。
解决方案(仅供参考)
⚠️ 以下方案结合实际业务场景选择,实际部署前请先在测试环境验证兼容性。
# 安装 orjson
pip install orjson
import orjson
# 序列化:orjson.dumps() 返回 bytes(不是 str)
raw_bytes = orjson.dumps(data)
# 如果接口返回 str,需要 decode
json_str = raw_bytes.decode()
# 反序列化
parsed = orjson.loads(raw_bytes)
关键注意: orjson.dumps() 返回的是 bytes,不是 str。Flask 里直接返回 bytes 没问题,Django/DRF 需要注意响应类型。
# Flask 直接返回
from flask import Flask, Response
app = Flask(__name__)
@app.route("/api/data")
def get_data():
raw = orjson.dumps(data)
return Response(raw, mimetype="application/json")
# Django HttpResponse 返回 bytes
from django.http import HttpResponse
def api_view(request):
raw = orjson.dumps(data)
return HttpResponse(raw, content_type="application/json")
效果对比
上线后的实际效果(接口数据量约 800KB):
| 指标 | 优化前(json) | 优化后(orjson) |
|---|---|---|
| 接口 P99 响应时间 | 320ms | 110ms |
| CPU 占用峰值 | 78% | 31% |
| QPS | ~120 | ~380 |
经验总结
-
先定位再优化。 不要假设 JSON 是瓶颈,用 cProfile 或 py-spy 实际跑一遍,看火焰图找热点。
-
orjson 快是有代价的。 它依赖编译环境,安装包比 json 重,首次部署注意兼容性测试。另外 dumps 返回 bytes 不是 str,迁移时需要改调用方。
-
序列化不是唯一解。 如果接口数据量巨大且结构固定,可以考虑 Protocol Buffers 或 MessagePack,它们的序列化速度比 JSON 更快,但代价是调试复杂度上升。
-
读写分离场景效果更明显。 如果读写压力都大,CPU 在序列化上省下来的时间可以让服务承接更多并发。
-
异步框架配合更好。 在 asyncio 环境下,orjson 的速度优势会被放大,因为异步 IO 等待的时间里 CPU 可以专心完成序列化。
⚠️ 再声明:orjson 的提升幅度和你的数据量、数据结构复杂度相关,并非所有场景都有 5 倍以上的收益。小数据量场景下差异不明显,谨慎选型。
有问题欢迎留言交流 🚀