企业 API 的 SLA 一旦写进合同,可用性就从技术指标变成法律义务。本文以"别违约"为出发点,讲网关层稳定性的三件事:租户级限流(独立配额 + 租户维度聚合,并处理聚合点自身的故障域问题)、上游故障降级(统一 OpenAI 风格协议 + 错误率与 P95 双信号切换 + 分级降级 + 备选通道自带限流)、灰度升级不违约(按租户灰度 + 影子对比 + 一键回滚 + 合同维护窗口与客户监控口径对齐)。核心结论:熔断是"不调了",降级是"用更便宜的替代";限流聚合点、降级目标、灰度条款三处最容易被低估,需提前兜底。
消费级 API 挂一挂,用户骂两句也就过去了。企业 API 不一样:一旦 SLA 写进合同,可用性就不是技术指标,是法律义务——达不到,要赔钱、要背上"履约事故"的名声。
所以我们做稳定性,出发点从来不是"让系统更健壮",而是"别违约"。落到网关层,主要是三件事:租户级限流、上游故障降级、灰度升级不违约。
租户级限流:不能一个租户打爆所有人 很多人做限流是"全局一个桶",全平台共享一份配额。这是企业场景的第一个坑:一个调失控的租户,能把所有租户一起拖死——和第一篇里那个被内部爬虫打挂的查询接口是同一类问题,只是放大到了多租户。
如果按每个租户独立的 QPS / token 配额,超了就限它自己,绝不连累别人。配额按租户的合同档位动态下发到网关节点。这样配置会有很多意想不到的便捷。限流要防"绕过"——同一个租户用多把 key、多台机器,照样要按租户维度聚合统计,而不是按 key 各算各的,否则多开几把 key 就绕过了限制。
但"按租户聚合"这句话说起来轻巧,落下去要回答一个绕不开的问题:聚合状态放在哪?
放单机内存,多台网关各算各的,租户开三台机器打过来,每台都以为自己没超——聚合等于没做。
放集中式计数(Redis / etcd),能聚合了,但计数服务本身成了新的故障域:它抖一下,全平台限流判定跟着抖,SLA 反而更脆。
折中方案是按租户一致性哈希路由到固定节点聚合,代价是节点迁移时要处理计数漂移。
选择集中式计数 + 本地兜底:集中计数做准,但计数服务不可用时降级为"本地估算 + 保守阈值",宁可误限一点,也不让限流层自己变成打爆全场的单点。限流器的聚合点本身就是故障域,这一点必须在设计时就想清楚,而不是等它挂了才发现。
上游故障降级:多模型 / 多供应商时靠统一协议兜底 当接入的是多模型、多供应商(DeepSeek、Kimi、Qwen 这些上游)。这里最大的风险是单点依赖:只要某一家上游波动,整条链路就跟着抖,SLA 说破就破。
所以在网关层做了一件事:统一协议 + 故障自动切换。把各家上游的接口标准化成同一套格式(OpenAI 风格),再在后面挂多个可选的"通道"。某个上游的 P95 延迟飙高、或者连续报 5xx 时,网关自动把请求路由到健康通道,客户端那端感知不到切换。
这个思路在网关模式里很成熟,但实际可能有两个坑:
切换不能只看状态码:上游 200 但响应慢,比直接报 5xx 更阴险。用"错误率 + P95 延迟"两个信号一起触发,单看哪个都会被坑。流式响应下这一点尤其明显——首包很快、后续卡住,状态码层面完全看不出来,得靠首包后 token 到达间隔这类信号补位。
切换要分级:不是所有请求都值得切。可以降级的(比如模型 A 换成模型 B)就切;不能降级的(比如客户指定了模型)就降级为清晰报错,别静默给个不对的结果。熔断是"不调了",降级是"用更便宜的替代"——两回事,别混。
还有一个容易被忽略的点:降级目标本身要有限流保护。模型 A 切到模型 B,B 的配额、上下文长度、输出格式可能都不一样;切过去不是零成本——B 的 P95 可能更差,或者 B 的配额已经被别的租户吃满。降级流量一窝蜂涌向同一个备选通道,就是二次打爆。所以我们的降级链上每一跳都挂着独立的配额和熔断,备选通道不是"兜底池",是"有容量上限的兜底池"。
灰度升级:怎么改网关不违约 网关是命门,改它最容易出事。升级网关策略 / 版本,靠的是按租户灰度:
先把新策略灰度到低价值、可容忍出错的租户,观察错误率和延迟,稳定了再放大到高价值租户。
灰度期间要做影子对比:新逻辑先跑一份影子流量,和线上结果比对,不一致就说明有问题,先别切。
全程带一键回滚:出问题第一时间切回旧策略,宁可退回,也不让故障延续。
影子对比有个现实成本要算:对 LLM 网关来说,影子流量是真金白银的 token 消耗。灰度期间影子比例开多大、预算上限多少、超了是降比例还是停影子,都得提前定好,否则"为了稳"的灰度本身先烧掉一笔不该烧的钱。
但这里有个合同层面的坑:灰度期间某个租户出问题,算不算违约?最好在合同里专门定义了"维护窗口"和"灰度排期"条款,让"为了稳定而做的升级"不成为违约点。否则技术上做得再稳,合同一抠字眼照样赔钱。
更隐蔽的是口径对齐:合同里写了维护窗口,但客户侧的监控仪表盘往往只认可用性百分比,不认你的条款。条款上"不算违约"、客户账上"记了一次故障",照样要有歧义。所以灰度排期不只是法务文件,得和客户侧的监控口径、告警规则一起对齐,合同条款和客户实际观测到的数字必须是同一个口径,否则条款是纸面的。
总结 SLA 进合同之后,稳定性的每一行代码都有了"钱"的属性。租户级限流保证不互相连累,统一协议 + 故障自动切换兜住多供应商的单点风险,按租户灰度 + 一键回滚让升级不变成事故。
三个容易被低估的坑,一并记住:
限流器的聚合点是新的故障域,得给它兜底;
降级目标本身要限流,备选通道不是无底洞;
熔断是"我不调了",降级是"我用更便宜的替代",两回事别混;灰度条款要和客户监控口径对齐,否则合同上不算违约、客户账上照样算故障。 n'dnd