How to Handle API Failover and High Concurrency?
正确的分类:①401/403——这家上游的密钥被拒,换家且冷却;②404——这家没这个模型,换家不冷却;③429——限流,冷却并换家;④5xx——上游故障,冷却换家;⑤逾时/连线错——冷却换家。400/422 这类参数问题各家行为不同,稳妥做法也是先换一家试,全部拒绝才回真实 4xx。
OlithmRouter 的实作:所有 4xx/5xx/逾时都会换下一家,全部拒绝才把真实状态码回给客户端(SDK 才能正确分类「请求错了」还是「服务挂了」);冷却以(上游×模型)为键、指数退避,冷却中的上游排到候选尾端但仍保留——避免「全冷却时直接全灭」。
上游逾时要涵盖「连线+回应头+首字」,而不是只看 body。设太长(如 300 秒):一个假死的上游会吃掉整个重试预算;设太短:慢模型会被误杀。建议按模型等级区分,并确保「逾时也算失败、触发换家」。
流式请求要注意:换家只能在「还没向客户端吐出任何位元组」之前进行;已经开始输出后上游断流,只能中止并由客户端重试——这是所有闸道的物理限制。
①配置刷新单飞:密钥/上游清单不能每个请求都拉一次,要用定期缓存+单飞刷新,否则高并发时配置端点会被打爆。②冷却不挡路:故障上游进冷却后仍保留在候选尾端,全冷却时照样服务而不是 503。③并发分摊:请求量超过阈值时把轮转起点平移到其他上游,避免全部压在第一家。
OlithmRouter 另有会话黏性(同一对话黏同一家上游)——让上游的 prompt 缓存持续命中,多轮对话的成本直接下降,且黏性只是「偏好」不是「锁定」,上游故障时照样换家。
闸道做得再好,客户端也要守基本礼仪:指数退避重试、尊重 429 的 Retry-After、以及把 request_id 写进自己的日志以便对帐。两边配合,上游故障才能真正「使用者无感」。