← 返回资讯
赵一鸣
产品评测编辑
已审核

模型API故障平均恢复47分钟,我用Nginx把损失降到零

上周三凌晨两点零七分,PagerDuty 炸了。

模型API故障平均恢复47分钟,我用Nginx把损失降到零

模型API故障平均恢复47分钟,我用Nginx把损失降到零


当 DeepSeek、OpenAI 和 Claude 同时罢工时,我是怎么用 Nginx 救场的

上周三凌晨两点零七分,PagerDuty 炸了。

生产环境的智能客服系统全线崩溃。查了半天才发现,是我们依赖的那家模型 API 突然限流。当时只接了一个供应商。就一个。那天晚上我蹲在机房里改 Nginx 配置,心里反复念叨一句话:都他妈 2025 年了,谁还敢把鸡蛋放一个篮子里啊?

大家好,我是 Raj Patel。DevOps 工程师,被模型 API 稳定性折磨了整整三年。今天想跟你聊聊我最近搞的一套东西——让 DeepSeek、OpenAI、Claude 轮流干活,哪个挂了自动切走。

就这么简单。

为什么你需要关心这个?

先看几个数据吧:

翻译成人话:不管哪家模型厂商吹得多牛,它都会挂。 区别只是挂多久,以及你会损失多少钱。

我去年接了个大客户的智能客服项目。图省事,全怼了 OpenAI 的 API。第一个月好好的,第二个月赶上他们大规模故障——2024 年 11 月那次,你们应该还有印象。客户电话直接打到我手机上,凌晨三点。那种感觉,懂的都懂。不懂的希望你永远别懂。

方案架构:三层防线

先用 Mermaid 画个简图吧:

MERMAID
graph TB
 A[客户端请求] --> B[Nginx 反向代理]
 B --> C{负载均衡器}
 C -->|权重70%| D[DeepSeek API]
 C -->|权重20%| E[OpenAI API]
 C -->|权重10%| F[Claude API]
 D --> G{健康检查}
 E --> G
 F --> G
 G -->|故障| H[故障转移队列]
 H --> I[备用模型池]
 I --> J[本地部署模型]

核心思路一句话:永远不让任何一个模型成为单点故障。

等等,这里我要更正一下。上面说的是"永远不",但实际上你不可能完全避免单点故障。比如你的 Nginx 本身就可能挂。所以准确的说法是:把故障域缩小到你承受得起的范围。 好,我们继续。

第一层:智能路由与负载均衡

用的 OpenResty(就是 Nginx + Lua),关键配置长这样:

NGINX
upstream model_backend {
 # 主模型池
 server deepseek-api.internal weight=70 max_fails=3 fail_timeout=30s;
 server openai-api.internal weight=20 max_fails=3 fail_timeout=30s;
 server claude-api.internal weight=10 max_fails=3 fail_timeout=30s;
 
 # 备份模型(仅在主池全挂时启用)
 server local-llm.internal:8080 backup;
 
 # 健康检查
 check interval=3000 rise=2 fall=5 timeout=1000 type=http;
 check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
 check_http_expect_alive http_2xx http_3xx;
}

但这里有个坑。

不同模型的 API 格式不一样。OpenAI 是 Chat Completions,DeepSeek 兼容它,但 Claude 的 Messages API 参数结构完全不同。直接轮询肯定报错。

这就是异构模型的麻烦。所以我加了个适配层:

LUA
-- 请求转换中间件
local function transform_request(model_type, original_body)
 local transformed = {}
 
 if model_type == "claude" then
 -- OpenAI格式转Claude Messages格式
 transformed.model = original_body.model
 transformed.messages = {}
 for _, msg in ipairs(original_body.messages) do
 table.insert(transformed.messages, {
 role = msg.role,
 content = msg.content
 })
 end
 transformed.max_tokens = original_body.max_tokens or 1024
 transformed.system = original_body.messages[1].role == "system" 
 and original_body.messages[1].content 
 or nil
 elseif model_type == "deepseek" then
 -- DeepSeek兼容OpenAI格式,直接透传
 transformed = original_body
 end
 
 return transformed
end

这套转换层写了大概 300 行 Lua。踩坑最多的是 Claude 的 system prompt——它要求 system 是顶层参数,OpenAI 是放 messages 数组里的。你知道我怎么发现的吗?

上线那天,Claude 那边全是 400 错误。查日志查了两个小时。

嗯...这个说起来还挺复杂的。主要是我当时脑子抽了,以为 Anthropic 的 API 跟 OpenAI 一样。后来看了官方文档才发现,人家 2024 年 3 月就改成顶层参数了。我一直用旧版本的 SDK,完全没注意到。

第二层:故障检测与自动切换

光有负载均衡不够,还得快速发现故障并切走流量。我用了三个维度的健康检查:

1. 心跳检测:每 3 秒 ping 一次 /health

2. 业务探针:每分钟发一个真实请求,检查返回质量。成本大概 0.001 美元,我觉得值

3. 延迟监控:P99 延迟超过 5 秒自动降权

关键代码:

LUA
-- 动态权重调整
local function adjust_weights(upstream_name)
 local peers = ngx.shared.upstream_peers:get(upstream_name)
 
 for _, peer in ipairs(peers) do
 local latency_p99 = get_peer_latency(peer.name, "p99")
 
 if latency_p99 > 5000 then -- 超过5秒
 local new_weight = math.max(1, peer.weight * 0.5)
 update_peer_weight(upstream_name, peer.name, new_weight)
 ngx.log(ngx.WARN, "降低 ", peer.name, " 权重至 ", new_weight)
 end
 
 -- 连续失败5次直接下线
 if peer.fail_count >= 5 then
 set_peer_down(upstream_name, peer.name, true)
 send_alert("模型API故障: " .. peer.name)
 end
 end
end

有个血泪教训:别只依赖 HTTP 状态码。

有次 OpenAI 返回的全是 200,body 里却是空内容。健康检查完全没发现。用户那边看到的就是"助手正在思考..."然后永远没结果。后来我加了个内容长度校验——content-length 小于 50 字节直接标记失败——才算堵上这个洞。

第三层:降级策略与本地兜底

所有外部 API 全挂了怎么办?

我在本地跑了个量化版 Qwen-7B。效果差点,但至少不会完全不可用:

YAML
# docker-compose.yml 本地模型服务
version: '3.8'
services:
 local-llm:
 image: vllm/vllm-openai:latest
 command: >
 --model Qwen/Qwen-7B-Chat
 --quantization awq
 --max-model-len 4096
 --gpu-memory-utilization 0.85
 deploy:
 resources:
 reservations:
 devices:
 - driver: nvidia
 count: 1
 capabilities: [gpu]
 ports:
 - "8080:8080"

单张 A10 上跑。推理速度大概 30 tokens/s,比云端慢不少。但处理简单问答够用。

关键是它不会限流、不会欠费、不会半夜突然改 API 格式。 据我了解,很多公司都开始搞这种混合方案了。圈子里管这叫"云边协同",听着挺高大上,其实就是给自己留条后路。

这套方案帮我扛住了什么

说三个真事儿。

案例 1:春节 DeepSeek 限流

2025 年春节期间,DeepSeek 突然限流。我们的主模型(权重 70%)12 秒内不可用,系统自动切到 OpenAI 和 Claude。用户那边完全无感知。等 DeepSeek 恢复了,权重自动回升。

那几天我睡得特别香。真的。

案例 2:Claude 的奇葩参数

有次 Claude 突然要求 max_tokens 必须大于 1(之前允许 0)。我们的部分请求开始报错。故障检测发现错误率从 0.1% 飙升到 15%,自动把 Claude 权重降到 0,同时给我发了条飞书。花了 20 分钟修好适配层,重新上线。这 20 分钟里,流量完全没受影响。

大概少赔了七八万吧。我没细算。

案例 3:意外降本

之前全用 OpenAI,一个月 8000 刀。接入 DeepSeek 后(价格是 OpenAI 的 1/5),设 70% 权重,月费降到 3200 刀。而且响应速度更快了——DeepSeek 的 P50 延迟比 OpenAI 低了 40%。

省下的钱请团队吃了顿海底捞。剩下的大概够买张 4090。

你需要准备什么

前置条件:

快速上手:

1. 克隆配置模板:

BASH
git clone https://github.com/rajpatel/multi-model-gateway.git
cd multi-model-gateway

2. 改 config/models.yaml,填 API Key:

YAML
models:
 deepseek:
 endpoint: https://api.deepseek.com/v1
 api_key: ${DEEPSEEK_API_KEY}
 weight: 70
 openai:
 endpoint: https://api.openai.com/v1
 api_key: ${OPENAI_API_KEY}
 weight: 20
 claude:
 endpoint: https://api.anthropic.com/v1
 api_key: ${CLAUDE_API_KEY}
 weight: 10

3. 启动:

BASH
docker-compose up -d

4. 测试故障转移:

BASH
# 模拟 DeepSeek 挂了
docker stop deepseek-mock
# 发个请求,应该自动切
curl -X POST http://localhost:8080/v1/chat/completions \
 -H "Content-Type: application/json" \
 -d '{"model":"auto","messages":[{"role":"user","content":"你好"}]}'

完整的部署文档和监控面板配置放在仓库 Wiki 了。

说点实在的

这套方案跑了快一年。

我最深的体会:别把任何模型厂商当信仰。 今天 DeepSeek 性价比炸裂,明天 OpenAI 可能出个 killer feature,后天 Claude 又降价了。你要做的是让系统足够灵活。

技术上没什么黑魔法,Nginx + Lua + Docker,老一套。真正的难点是适配不同模型的差异——每个厂商改 API 我都得跟着改。2024 年 Anthropic 改了 3 次,OpenAI 改了 2 次,DeepSeek 还好,基本兼容 OpenAI 格式。维护这些 Lua 脚本挺累的,但省下的钱和时间,我觉得值。

圈子里有人用 LiteLLM 或者 One API 这种现成网关。我自己还没深入试过——如果能省掉那些 Lua 脚本的维护,我绝对愿意切。用过这俩的朋友,评论区聊聊体验?

标签: #模型API #负载均衡 #故障转移 #DevOps #DeepSeek #OpenAI #Claude #Nginx #高可用架构


PS:GitHub 仓库 Star 破 500 的话,我下周出视频教程,手把手带你从零搭这套系统。看文档和真刀真枪干活,感觉真的差很多。

PPS:有没有人跟我一样觉得 vLLM 的文档写得一言难尽?0.6.3 版本的 migration guide 我看了三遍才搞明白。

59
847 阅读
5 评论
分享
链接已复制
编辑说明

本文由 MakeSense 编辑团队撰写并审核。文中引用的数据和观点均经过交叉验证,如有疏漏欢迎在评论区指正。最后更新:2026年06月27日 17:33

赵一鸣

产品评测编辑

前产品经理,现专注 AI 工具评测。实测过 30+ 款 AI 产品,擅长横向对比和用户体验分析。

读者评论 5

前端工程师 1周前
代码示例很清晰,直接用到项目里了。
回复 点赞 (6)
技术小白 1周前
作为非技术人员也看懂了,感谢作者的通俗讲解。
回复 点赞 (3)
Dev小王 2周前
终于有人把这个说清楚了,收藏了。
回复 点赞 (8)
A
AI研究员 3天前
观点有道理,不过我觉得还需要考虑算力成本的问题。
回复 点赞 (11)
M
创业者Mark 6天前
正在做相关方向,这篇文章给了我不少启发。
回复 点赞 (7)