第一次在每秒上千请求的生产环境调用大模型时,我的服务在30秒内崩溃了三次。这不是简单的技术选型问题,而是涉及资源调度、流量控制、错误处理等多维度的系统工程。经过半年实战,我们最终将大模型API的99分位响应时间控制在800ms以内,错误率低于0.5%。以下是血泪换来的五个关键教训:
初期我们直接在主业务线程同步调用大模型API,导致:
正确姿势:
python复制# 使用异步协程池控制并发
from aiomultiprocess import Pool
async def process_request(prompt):
async with Pool(processes=50) as pool:
results = await pool.map(chat_completion, prompts)
return results[-1] # 只取最新结果
# 配合Nginx限流
limit_req_zone $binary_remote_addr zone=mllimit:10m rate=100r/s;
关键参数:并发数=平均响应时间(ms)/1000 * QPS。当P99为600ms时,100QPS需要至少60个并发槽位
当用户连续发送10条消息时,传统做法是每次都全量发送历史记录:
json复制{
"messages": [
{"role": "user", "content": "消息1"},
...
{"role": "user", "content": "消息10"}
]
}
这导致:
优化方案:
python复制from transformers import pipeline
summarizer = pipeline("summarization")
def summarize_history(history):
return summarizer(" ".join(history), max_length=150)
初期统一设置3秒超时,结果:
分级超时策略:
| 请求类型 | 超时阈值 | 重试策略 |
|---|---|---|
| 文本分类 | 800ms | 快速失败不重试 |
| 短文本生成 | 2s | 指数退避重试2次 |
| 长文档摘要 | 8s | 降级返回进度条 |
实现代码:
python复制def adaptive_timeout(prompt):
prompt_type = classify_prompt(prompt)
timeout = {
'classification': 0.8,
'short_gen': 2,
'long_form': 8
}.get(prompt_type, 2)
try:
return asyncio.wait_for(
call_model(prompt),
timeout=timeout
)
except TimeoutError:
return fallback_handler(prompt)
某次API波动时,我们的简单重试逻辑导致:
智能重试方案:
python复制from circuitbreaker import circuit
@circuit(
failure_threshold=5,
recovery_timeout=60
)
def safe_retry(prompt):
for attempt in range(3):
try:
return call_model(prompt)
except ModelException as e:
if e.status_code not in [502, 503]:
raise
sleep(2 ** attempt)
凌晨发布的容器遇到:
预热方案:
dockerfile复制HEALTHCHECK --interval=5s --timeout=3s \
CMD curl -f http://localhost:8000/warmup || exit 1
python复制def warmup():
# 加载小规模测试数据
test_prompts = load_sample_data()
# 梯度增加并发
for concurrency in [1, 5, 10, 20]:
with ThreadPoolExecutor(concurrency) as ex:
list(ex.map(call_model, test_prompts))
# 保持心跳
while True:
call_model("ping")
sleep(300)
code复制用户请求 → 负载均衡器 →
├─ 快路径:简单请求 → 本地轻量模型
└─ 慢路径:复杂请求 → 大模型API集群
├─ 主集群(AWS us-east)
├─ 备集群(GCP asia-east)
└─ 降级服务(HuggingFace本地模型)
上周处理的实际案例:
优化后效果:
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 错误率 | 12% | 0.3% |
| 平均延迟 | 2.4s | 1.1s |
| Token成本 | $18/天 | $9/天 |
经过实测可用的技术栈组合:
特别提醒:避免在Go中使用全局http.Client调用大模型API,会引发端口耗尽。推荐使用:
go复制client := &http.Client{
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 50,
IdleConnTimeout: 90 * time.Second,
},
Timeout: 10 * time.Second,
}