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

上游模型崩了怎么办?我们踩了3次坑才搞定的熔断方案

上周三下午 3 点 12 分,我们的 API 聚合平台挂了。整整 47 分钟。

上游模型崩了怎么办?我们踩了3次坑才搞定的熔断方案

上游模型崩了怎么办?我们踩了3次坑才搞定的熔断方案


上周三下午 3 点 12 分,我们的 API 聚合平台挂了。整整 47 分钟。

原因特别蠢——有个模型供应商的 gpt-4-turbo-preview 端点超时,把整个调度线程池拖死了。老板在飞书群里发了三个问号,我当时正在喝咖啡,差点把杯子扣键盘上。

真的,那一刻想死的心都有。


这件事逼着我把模型调度和高可用的设计从头捋了一遍。我发现市面上聊 API 聚合的文章挺多,但真正讲清楚「上游炸了你该怎么办」的,少之又少。今天就把我踩过的坑、流过的泪,还有现在的方案,全盘托出来。

我们到底在调度什么

先对齐场景。

我们平台接了 7 家模型供应商,OpenAI、Claude、国内的文心一言、通义千问、DeepSeek、智谱,还有 MiniMax。用户发一个请求过来,调度层要在几百毫秒内决定四件事:

看着简单对吧?

实际坑多到能填满一个工体。我说真的。

我们最初的设计特别 naive,就是个简单的轮询。我想着反正各家模型都差不多,平均分配就完事了。结果 OpenAI 一抽风,整个平台跟着陪葬——所有请求都在排队等那个已经超时的连接,线程池瞬间打满。

那是 2024 年 3 月的事。我记得特别清楚,因为那天我刚跟女朋友吹嘘说「我们的架构很稳」。

打脸来得太快。

调度策略:从轮询到智能路由

第一版:加权轮询(已废弃)

PYTHON
# 2023 年 11 月的代码,现在看简直想删库跑路
def select_provider(request):
 providers = get_available_providers()
 provider = providers[current_index % len(providers)]
 current_index += 1
 return provider

这个方案的问题在哪?它完全不管每个供应商的实时状态。有一次 Claude 的 API 延迟飙到 13 秒,我们的轮询还在傻傻地给它分配请求。用户体验直接崩了,工单群里骂声一片。

嗯...准确说是 12 个工单。我数过。

第二版:健康检查 + 动态权重

后来我们加上了健康检查,每 30 秒 ping 一次各供应商的 /v1/models 端点。我当时觉得这方案挺聪明的。

然后就被现实教育了。

去年双十一那天——别问为什么一个海外业务要凑双十一的热闹,运营那边搞的活动——某个供应商在两次健康检查的间隙突然限流了。就那 30 秒的窗口期,我们积压了 2300 多个失败请求。

Redis 队列直接爆了。

等等,这里我要更正一下。不是 Redis 队列爆了,是 Celery 的任务队列内存溢出。Redis 本身没问题,是我们没给 Celery 设 task_soft_time_limit,导致任务堆积在 worker 内存里。这个细节很重要,因为后来我们专门给 Celery 加了 task_soft_time_limit=45task_time_limit=60 的配置。

现在的方案:多维度评分 + 熔断

目前用的是实时评分系统。每次请求完成后,都会更新对应供应商的分数:

CODE
得分 = 响应速度(40%) + 成功率(35%) + 成本(15%) + 负载(10%)

代码大概是这样的:

PYTHON
class ProviderScorer:
 def calculate_score(self, provider_stats):
 latency_score = self.normalize_latency(provider_stats.p99_latency)
 success_score = provider_stats.success_rate * 100
 cost_score = self.calculate_cost_efficiency(provider_stats.avg_cost)
 load_score = 100 - provider_stats.current_load
 
 return (
 latency_score * 0.4 +
 success_score * 0.35 +
 cost_score * 0.15 +
 load_score * 0.1
 )

但我必须说实话——这 4 个权重的具体数值,我们到现在还在调。0.4、0.35 这组参数是 2024 年 6 月定的,在 GPT-4o 发布之后改过一次。因为 GPT-4o 比 GPT-4 快太多了,原来的延迟权重偏低,导致调度器过度偏爱 OpenAI,把成本冲上去了。

现在可能还要再调。毕竟 DeepSeek V3 出来之后,性价比这条线完全被改写了。

光有评分还不够。

关键是熔断。

我们用的是滑动窗口熔断器,不是简单的「失败 N 次就熔断」。窗口大小 60 秒,如果这 60 秒内错误率超过 50%,自动触发熔断,冷却 30 秒后放几个请求探测。用 Hystrix 的思想,但我们是自己写的,因为 Go 生态里没找到特别合适的库。

说到这个,我其实想用 Resilience4j,但我们后端是 Go 写的...嗯,这个选择当时争议挺大的,有同事坚持用 Java 就是因为生态成熟。后来我们折中,熔断器自己写,其他中间件尽量用现成的。

高可用的三个关键点

1. 请求级超时控制

这是我用一次线上事故换来的教训。

2024 年 4 月 17 号,我记得这个日期。因为第二天是我生日,结果前一天晚上在修线上 Bug。

当时我们设置的是全局超时 30 秒,用的 Nginx 的 proxy_read_timeout。结果某个供应商的某个模型(就不点名了)响应特别慢,把所有 worker 线程都占满了。新的请求根本进不来,健康检查也被阻塞——死锁了,属于是。

现在的做法是分层超时

每个供应商有独立的 goroutine pool,用 Go 的 channel 做背压控制。池子满了就直接降级,不会影响其他供应商。

这个设计帮我们扛过了 2024 年 8 月 OpenAI 那次全球性宕机。当时整个 AI 圈都在哀嚎,我们这边用户基本无感——调度器自动切到了 Claude 和 DeepSeek。

2. 结果缓存与降级

不是所有请求都需要实时调模型。

我们发现很多用户会重复问类似的问题,尤其是代码生成和翻译场景。有人问「用 Python 写个快速排序」,一天能被问几百次。

我们加了一层语义缓存,用的是 pgvector(v0.6.0,当时最新版),用 OpenAI 的 text-embedding-3-small 做向量化。相似度阈值设的 0.92,命中率大概在 15-18% 左右。

看着不高对吧?

但高峰期的 18% 意味着每秒少调用 40 次 API。按 GPT-4 的定价算,一天能省差不多 200 刀。不多,但够我们团队喝一个月咖啡了。

降级策略更重要。当所有高端模型都不可用时,自动切到备用模型。比如 GPT-4o 挂了降级到 GPT-4o-mini,Claude Opus 挂了降级到 Sonnet。质量差一点,但总比直接报 503 强。

这里有个坑。不同模型的输出格式不一样,尤其是 function calling 的响应结构。我们写了个适配层做格式统一,但这个适配层本身也出过 Bug——去年 9 月有一次,Claude 的 tool_use 格式更新了,适配层没跟上,解析失败率飙升。那次是被用户先发现的,丢人。

3. 多区域部署

这个其实是被逼出来的。

2024 年 5 月,阿里云华北某机房的骨干光缆被施工队挖断了。真的,就是挖断了。我们整个华北地区的服务全挂,持续了 3 个多小时。

那天之后我们开始搞多区域部署。

现在在三个区域部署了调度节点:阿里云上海、AWS 东京、Azure 新加坡。用 Cloudflare 做 Anycast 就近接入。切换逻辑是自动的:

CODE
if 主区域可用性 < 99%:
 切换流量到备用区域
 钉钉通知 oncall
 记录 incident timeline

切换大概需要 12-17 秒,会有少量请求失败。但比整个挂掉强一万倍。

不过说实话,多区域部署的成本不低。数据同步、跨区域延迟、运维复杂度,都是钱。我们也是被那根挖断的光缆逼的,不然可能到现在还是单区域。

成本优化的野路子

调度做得好,真的能省不少钱。我们现在的策略:

上个月我们通过优化调度策略,成本降了 23%,响应速度反而提升了 15%。

老板终于不发问号了,改发大拇指了。

不过我得说,这个成绩有一半是因为 DeepSeek 太便宜了,他们 V3 的定价简直是价格屠夫。我们调度器现在给 DeepSeek 的权重明显偏高,因为性价比实在香。

写在最后

搞 API 聚合平台的模型调度,本质上是在可用性、成本、性能之间找平衡。没有银弹,都是根据业务场景一点点调出来的。

我们现在的架构也不是完美的。跨区域切换时的一致性保证还不够好,多供应商的流式响应合并也有优化空间——SSE 格式各家实现不一样,有的用 data: 前缀,有的不用,有的 event: 字段是空的,合并起来特别恶心。

如果你也在做类似的事情,或者有更好的方案,真的很想听听。

你们怎么处理供应商故障的?有没有遇到过特别奇葩的线上事故?评论区聊聊呗。

我请喝咖啡——精神上的 ☕

#API网关 #高可用架构 #模型调度 #后端开发 #系统设计

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

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

赵一鸣

产品评测编辑

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

读者评论 5

运营小陈 4天前
转发到团队群了,大家都觉得有参考价值。
回复 点赞 (4)
数据分析师 1周前
数据引用很扎实,建议补充一下近三个月的最新数据。
回复 点赞 (9)
产品经理阿杰 1周前
从产品角度看,这个方向确实有机会,但商业化路径还需要验证。
回复 点赞 (15)
张工 1周前
写得很实在,特别是实测对比那部分,跟我自己的使用感受一致。
回复 点赞 (12)
前端工程师 2天前
代码示例很清晰,直接用到项目里了。
回复 点赞 (6)