接口平时好好的,一到活动或批量任务上来就超时、限流、排队,加机器又不见得管用——这类问题往往不是某一处配置写错,而是并发控制、超时、降级、观测几件事没串起来。这篇按工程落地的顺序,把该先定什么、该量什么、什么时候不该硬扛讲清楚,具体数字口径一律到站内对应页面核对。
接口平时好好的,一到活动或批量任务上来就超时、限流、排队,加机器又不见得管用——这类问题往往不是某一处配置写错,而是并发控制、超时、降级、观测几件事没串起来。加机器只能抬高某一层的天花板,如果瓶颈在下游的并发额度上,堆再多实例也只是把排队挪个位置。
这篇按工程落地的顺序讲:该先定什么、该量什么、什么时候不该硬扛。所有涉及具体数字的地方——比如各家接口的并发额度、延迟参考值——都不在这里写死,请到站内对应页面核对当时的数字。
先把基线和瓶颈量出来,再谈架构
动手改架构之前,先确认瓶颈到底在哪一层。接入层的连接数、应用层的线程或协程池、下游模型或数据库的并发上限,这三者的天花板经常差一个数量级:你可能拼命优化应用,结果排队全发生在下游那一段。判断顺序是从最下游往上量,而不是从最上游往下猜。
- 先分清瓶颈在哪一层:接入层连接数、应用层线程/协程池、下游模型或数据库的并发上限,三者天花板通常差一个数量级
- 量单请求的基线延迟和尾延迟,尾延迟决定要留多少余量,平均值好看不代表没事
- 把每个请求拆成排队时长、实际处理时长、下游等待时长三段记录,否则扩容只能靠猜
- 什么情况下不适用:如果 QPS 本身很低但偶发超时,多半是超时配置或网络问题,不是并发架构问题
| 现象 | 更可能的瓶颈 | 先做哪件事 |
|---|---|---|
| 低 QPS 偶发超时 | 超时配置或网络抖动 | 核对各层超时值与连接复用 |
| 高 QPS 普遍变慢 | 应用层线程池或下游并发额度 | 分段计时确认排队发生在哪里 |
| 突增流量大面积失败 | 缺少入口限流与排队缓冲 | 入口限流 + 队列上限先兜住 |
| 个别类型请求拖垮全局 | 没有隔离,慢请求占满资源 | 按任务类型拆独立池或独立实例 |
并发控制的主要手段与选用条件
并发控制不是选一个最强的手段,而是按流量形态组合。入口限流保系统整体,下游限流保依赖不被你打死,两者要分开设;令牌桶和漏桶的差别在于能不能应对突发,允许突发就倾向令牌桶,需要绝对平稳就倾向漏桶。选之前先问一句:这段流量是可延迟的,还是用户正盯着屏幕等。
- 入口限流先按整体和按用户各设一层,超限直接快速拒绝并返回明确提示;验证方式是压到超限,看拒绝是否干脆、有没有拖成长尾
- 排队与批处理把瞬时流量削成平稳消费,适合可延迟的批任务;交互请求必须设排队上限,等待时间比直接失败更伤体验
- 隔离与舱壁不同任务类型分到独立线程池或独立实例,验证方式是用一类慢请求打满,看其他类型的延迟是否受影响
- 退避重试与熔断只在幂等且失败可恢复时重试,重试带随机抖动;熔断阈值按下游健康度设,不是按自己的失败数设
有一类情况不适用上面的默认做法:强一致或带副作用的下游写操作,不要盲目重试,先确认幂等键再谈重试策略。同理,如果你的下游本身没有并发上限保护,盲目重试只会把压力放大,这时候要先做的是降级而不是重试。
超时、降级与容量取舍
超时要分层设置并逐层收敛:整体超时必须大于下游单次超时之和,否则重试还没结束,请求就被外层掐断了。常见错误是每层都填一个差不多的值,结果最外层比内层还短,重试逻辑等于白写。改完超时值之后,用一次人为的下游变慢来验证各层是否按预期退出。
- 降级预案清单
- 提前列出哪些请求可以返回缓存、哪些可以换更小的模型、哪些只能明确报错,并指定谁有权触发降级
- 延迟预算
- 业务能接受的端到端延迟上限,用它反推副本策略和跨区方案,而不是先定架构再补预算
- 可用性换性能
- 多副本与跨区容灾会带来额外一跳延迟,是否值得要看业务能不能接受这笔延迟开销
| 取舍点 | 偏高性能 | 偏高可用 |
|---|---|---|
| 副本与跨区 | 单区就近,少一跳延迟 | 多副本跨区,延迟换容错 |
| 重试策略 | 少重试、快速失败 | 多重试加抖动,容忍更长尾 |
| 降级触发 | 晚降级,尽量给完整结果 | 早降级,优先保证有响应 |
| 适用场景 | 交互类、延迟敏感 | 交易类、不能丢请求 |
什么情况下不该照搬在线服务这套取舍:内部离线任务可以牺牲可用性换吞吐,失败重跑即可,不必为它做跨区容灾和复杂降级。反过来,涉及资金或不可重放的操作,宁可慢一点也要把可用性拉满。具体额度与成本参考到站内价格与模型页面核对当时的数字。
上线后怎么验证没白做
架构改完不验证,等于没改。验证的关键是能回答两个问题:慢在哪里,贵在哪里。日志至少记下请求标识、并发档位、排队与处理耗时、命中的降级分支,缺一项,事后复盘就只能靠猜。压测要分阶梯加压并观察拐点,拐点之后的表现比单一峰值数字更有参考价值。
- 日志覆盖请求标识、并发档位、排队与处理耗时、命中的降级分支,缺一项就无法复盘
- 压测分阶梯加压找拐点,不只看一个峰值数字
- 灰度先放小流量,盯错误率和尾延迟两个指标,任一异常回滚而不是现场调参
- 定期复核并发上限,它会随下游额度、模型版本、依赖服务变化而变,别把一次调好的参数当永久结论
想把上面的判断落到自己系统上,建议从量基线开始,而不是从换中间件开始。测试工具、并发参考和各家接口的额度口径,站内都有现成入口,比自己拍脑袋设阈值靠谱。
下一步先拿站内测速与价格追踪页面核对你常用接口的并发和延迟参考口径,再回来定限流与超时参数,避免默认值拍脑袋。→常见问题
并发和并行到底是不是一回事,架构上要区分吗?
要区分。并发是同时处理多个任务的能力,并行是同一时刻真正同时执行。大多数 AI 接口场景的瓶颈在下游等待而非本地算力,所以先解决排队与超时,往往比加核数更有效。概念细节可以到基础概念词典对照。
限流一上来就 429,是该加机器还是该改架构?
先看 429 由谁返回。如果是入口限流,说明你给自己设的上限太低;如果是上游服务返回,加机器没用,只能排队、分批或退避。排查顺序是先定位返回方,再决定是调额度还是改节奏。
高可用一定要多副本吗?
不一定。单实例加快速重启和明确降级,对多数中小业务已经够用。多副本解决的是实例级故障,解决不了下游依赖整体挂掉的问题。先确认你的故障主要来自哪一层,再决定要不要为副本付那份延迟和成本。