AI网关调用方语义限流与突发削峰落地

日期:2026-09-19

一、项目背景

某开放平台接了上百个调用方,平时风平浪静,一个大促脚本一跑就把整条网关打满,其他正常业务全被拖死,运维只能临时掐线,掐完业务方又来投诉说接口全挂了。最早我们按 QPS 一刀切限流,结果误伤正常调用,保错人,被掐的那个恰恰是重要客户。这个项目让我重新想:限流不是把人挡外面,是让该过的过、该等的等。我们进场时,平台因为限流误伤吃过好几次客诉,调用方对网关的信任度在下降,有几个大客户甚至威胁要换平台,运维每天提心吊胆怕半夜被叫起来掐线,网关成了团队最怕的组件。

我们进场时网关是团队最怕的组件,运维每天提心吊胆怕半夜被叫起来掐线,几个大客户甚至威胁换平台,所以语义限流救的不只是稳定性,还有客户信任。

我们进场时网关是团队最怕的组件,运维每天怕半夜被叫起来掐线,几个大客户威胁换平台,所以语义限流救的不只是稳定性,还有客户信任,信任一崩后面全白做。

二、落地场景

我们做了语义级限流:不只看 QPS,还认调用方身份和请求语义(比如批量导出和单条问答分开计),突发流量识别后不硬拒,进排队削峰,按业务优先级放行;低优的批量任务排队,高优的实时问答先走。限流阈值和优先级都做成配置,压测后定,不拍脑袋。调用方接入时注册语义类型,网关按类型分别计量,运营能在看板上看到每个调用方的实时占用。重要客户走独立配额池,不被大促脚本连累,普通调用方按语义分档,突发时排队而不是被拒,体验好太多。

重要客户走独立配额池之后,不被大促脚本连累,普通调用方按语义分档,突发时排队而不是被拒,体验好太多,大客户留下来这件事比任何指标都硬。

三、关键技术挑战与解决思路

语义级限流是第一个坑,怎么定义语义得和调用方约定请求标签,我们让接入时注册语义类型,网关按类型分别计量,没注册的走默认档,避免有人钻空子不标语义白嫖配额。突发识别是第二个,要区分真突发和正常波峰,我们用了滑动窗口加突变检测,避免把晨高峰误判成攻击,否则每天早高峰都误伤,正常业务天天被拦。第三个是优先级调度,优先级错了会保错人,我们和业务一起排了等级,重要实时链路最高,批量导出最低,等级不是网关自己定,是业务拍板的。第四个是排队公平,排队不能无限等,我们给低优任务设了最大排队时长,超时就柔性拒绝并提示错峰,不然低优任务堆积把内存吃完。第五个是配置热更新,阈值压测后要能不停机改。

语义标签接入时就要约定,事后补大家都嫌麻烦,我们让接入文档里写清语义类型,新调用方注册时必填,否则走默认档限得很死,倒逼大家规范起来。

四、效果数据

限流误伤率比 QPS 一刀切下降明显,正常业务不再被连坐,客诉少了一大半,那几个威胁换平台的大客户留下来了;突发识别时效在秒级,排队削峰后链路可用性保持在高位,那次大促脚本的事故没再发生;平均排队延迟对低优任务可控,没出现无限等待把任务拖垮;运维从临时掐线变成看板调控,半夜被叫起来的次数归零,网关从最怕的组件变成最稳的组件。调用方对网关的信任度回来了,新客户接入也敢承诺稳定性了。优先级池隔离后,重要客户的 SLA 真正兜住了。

优先级池隔离后,重要客户的 SLA 真正兜住了,以前一刀切时大客户和小脚本平等抢,现在各走各的池,资源吵架的事没了,运维终于能睡整觉。

五、可复用经验总结

限流不能只按 QPS 一刀切,得认调用方和语义,不然一定是误伤正常业务。我们最早偷懒用全局 QPS,结果被一个大促脚本连累全平台,那是一次很丢人的故障,重要客户被掐了十几分钟,信任差点崩。改成语义分级加排队削峰之后,突发来了先排队而不是拒,体验好太多。但优先级一定和业务对齐再定,阈值得压测后再落,凭感觉设高了拦不住、设低了保错人。排队要有上限,无限排队看似友好,实际是把问题拖成更大的问题,柔性拒绝比卡死更负责任。配置热更新别省,压测后调阈值不用停机,运维才敢放心调。语义标签接入时就要约定,事后补大家都嫌麻烦。

配置热更新别省,压测后调阈值不用停机,运维才敢放心调,我们早期改阈值要发版,没人敢动,限流参数一直停在保守值,资源白白浪费好几个月。

案例片段(已脱敏): 网关语义限流与削峰配置片段:yaml ratelimit:  by: [caller, semantic]  semantics: { chat: 200, export: 20 }  burst:    detect: slide_window+突变    action: queue  priority: { chat: high, export: low }一次突发削峰日志:[BURST] caller=spider-77 qps 800 突变, queue depth=210 [QUEUE] low=export drained, high=chat passed [AVAIL] link 99.9%, 无连坐