共计 2177 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点分析
最近在项目中接入 ChatGPT API 时,我们发现当并发请求量增加时,响应延迟(Latency)会显著上升。经过压测和性能分析,主要瓶颈集中在以下几个环节:

- TCP 连接建立耗时:每次 API 调用都需要完成 TCP 三次握手和 TLS 协商,实测平均增加 200-300ms 延迟
- 令牌 (Token) 生成串行化:模型推理过程本质上是顺序生成令牌的过程,无法并行化处理
- 长上下文 (Context) 处理开销:当对话历史超过 2048 个令牌时,处理时间呈非线性增长
通过火焰图 (Flame Graph) 分析,在 10 并发请求下:
- 网络 I / O 耗时占比 35%
- 模型计算耗时占比 60%
- 序列化 / 反序列化占 5%
技术方案对比
请求批处理(Batch Processing)
适用于业务场景允许稍高延迟 (200-500ms) 但需要高吞吐的情况。通过合并多个用户请求为单个 API 调用:
- 优点:减少网络往返 (Round Trip) 次数
- 缺点:需要处理输出结果的路由分配
流式响应(Streaming Response)
适合需要实时显示生成结果的场景:
- 优点:首字节时间 (TTFB) 可缩短至 50ms 内
- 缺点:客户端需要适配分块接收逻辑
长轮询(Long Polling)
在传统轮询基础上改进的方案:
- 优点:兼容性最好
- 缺点:服务端资源占用较高
异步实现方案
基于 aiohttp 的异步调用
import aiohttp
from tenacity import retry, stop_after_attempt
@retry(stop=stop_after_attempt(3))
async def chat_completion(session: aiohttp.ClientSession, prompt: str):
payload = {
"model": "gpt-3.5-turbo",
"messages": [{"role": "user", "content": prompt}],
"stream": True # 启用流式响应
}
try:
async with session.post(
"https://api.openai.com/v1/chat/completions",
json=payload,
timeout=aiohttp.ClientTimeout(total=30)
) as resp:
async for chunk in resp.content.iter_chunks():
yield chunk[0].decode()
except Exception as e:
print(f"API 调用失败: {str(e)}")
raise
关键优化点:
1. 使用连接池复用 TCP 连接
2. 流式处理避免内存暴涨
3. 超时和重试机制保障稳定性
Redis 缓存实现
import redis
from functools import lru_cache
redis_client = redis.Redis(
host='localhost',
max_connections=100, # 连接池大小
socket_keepalive=True
)
class ChatCache:
@staticmethod
@lru_cache(maxsize=1000)
def local_cache(prompt: str) -> Optional[str]:
"""本地进程内缓存"""
return None
@staticmethod
async def get(prompt: str) -> Optional[str]:
# 先查本地缓存
if cached := ChatCache.local_cache(prompt):
return cached
# 再查 Redis
if cached := redis_client.get(f"chat:{prompt}"):
return cached.decode()
return None
生产环境配置
连接池大小计算
推荐值 = 最大 QPS × 平均响应时间(s) × 安全系数(1.2)
例如:
– 目标 QPS = 100
– 平均响应时间 = 0.8s
– 连接池大小 = 100 × 0.8 × 1.2 ≈ 96
Prometheus 监控指标
metrics:
- name: chatgpt_request_duration
type: histogram
labels: [status_code]
buckets: [0.1, 0.5, 1, 2, 5]
- name: chatgpt_concurrent_requests
type: gauge
常见问题排查
-
OOM 问题:监控上下文长度,建议设置硬限制
if len(context) > 3000: raise ValueError("上下文过长") -
TCP 连接断开:调整 Keepalive 参数
aiohttp.TCPConnector( keepalive_timeout=30, force_close=False ) -
日志脱敏:使用正则过滤敏感信息
import re def sanitize_log(text): return re.sub(r"(sk-)[a-zA-Z0-9]{48}", "[API_KEY]", text)
延伸思考
- 如何设计动态上下文窗口来平衡响应速度和质量?
- 在多区域部署时,怎样优化 API 端点选择策略?
- 对于超长对话场景,是否有更好的分块处理方案?
通过这些优化措施,我们的生产系统成功将 P99 延迟从 3.2s 降低到 1.1s,CPU 利用率提升 40%。关键在于找到适合自己业务场景的平衡点。
正文完
