aggregator-key-throughput-and-rate-limiting · ZH · 2026-10-21

批处理中途撞墙:一把聚合站 key 上的并发、限流与排队怎么设

本文针对使用聚合站 API key 进行批处理时常见的并发失败问题,解释共享 key 下并行 worker 加压失败的原因,并提供设定 worker 池大小、退避策略与本地缓冲的实用方法,帮助读者构建稳定的批处理流水线。

为什么并行 worker 一加压就失败

许多开发者习惯用同一把聚合站 API key 启动多个并行 worker 处理批任务,初期小规模测试顺畅,一旦加大并发就频繁遇到连接中断、响应超时或限流错误。根本原因在于聚合站对单 key 的并发请求数、单位时间请求数有内部限制,且该限制由所有使用该 key 的进程共享。

聚合站作为多模型统一入口,背后会对接不同上游供应商,每个上游的限流策略和可用容量并不一致。当你的 worker 池同时发起大量请求,聚合站需要转发到不同上游,任一上游触发限流都会导致对应请求失败,表现为你的 key 整体“撞墙”。

理解聚合站的限流层级

聚合站的限流通常分几个层级:

  • 单 key 并发上限:同一时刻允许的进行中请求数。
  • 单 key 速率限制:单位时间内的请求数或 token 数。
  • 上游模型限流:不同模型对应的供应商有各自的配额与限流规则。
  • 账户级配额:与充值余额或贡献 key 返佣相关的使用额度。

这些限制不会在 API 文档中精确公开,但会通过 HTTP 状态码(如 429)和响应头传递信号。批处理设计必须假设限制存在,并做好自适应。

如何设定 worker 池大小

worker 池大小不是越大越好,需要根据实测吞吐和错误率动态调整。

  1. 从保守起始值开始:先设较小并发(例如 2–4 个 worker),跑通完整流程并记录成功率与延迟。
  2. 逐步加压:每次增加 1–2 个 worker,观察错误率变化。当错误率明显上升时,回退到上一档。
  3. 区分模型:不同模型的上游容量不同,可为每个模型单独维护 worker 池,避免一个模型的限流拖垮全局。
  4. 保留余量:稳定并发上限的 70%–80% 作为日常 worker 数,留出应对突发重试的空间。

注意,聚合站 key 可能同时被其他程序或团队成员使用,worker 池规划应预留共享余量,而不是独占全部配额。

退避策略:让失败请求自动恢复

遇到限流或临时错误时,直接重试会加剧拥塞。应采用指数退避加随机抖动:

  • 首次失败后等待较短时间(如 1 秒)再试。
  • 每次重试将等待时间翻倍,并加上随机毫秒级抖动,避免多个 worker 同时重试。
  • 设置最大重试次数(如 3–5 次),超过后将该任务放入失败队列,稍后由人工或定时任务处理。
  • 对 429 状态码优先读取响应头中的重试建议(如有),没有则按退避策略执行。
  • 区分可重试错误(超时、429、5xx)与不可重试错误(4xx 参数错误),后者直接记录并跳过。

退避期间 worker 应释放并发槽位,让其他任务继续,而不是阻塞整个池。

本地缓冲:削峰填谷的关键

批处理任务往往集中提交,容易形成瞬时高峰。本地缓冲通过队列将任务平滑分发:

  • 使用内存队列或轻量消息队列暂存待处理任务,worker 从队列中按可控速率取任务。
  • 为每个模型维护独立队列,避免慢模型阻塞快模型。
  • 设置队列长度上限,超出时暂停生产者或落盘到文件,防止内存溢出。
  • 记录每个任务的尝试次数和最后错误,便于断点续跑和问题排查。

本地缓冲还能在聚合站短暂不可用时保护任务不丢失,等恢复后继续消费。

监控与动态调整

稳定的批处理需要持续观测:

  • 记录每个请求的延迟、状态码和模型名,按时间窗口统计错误率。
  • 当错误率超过阈值时自动降低 worker 数,恢复后再缓慢提升。
  • 关注聚合站返回的配额或限流提示,及时调整任务提交节奏。

小结

在共享 key 上跑批处理,核心是把并发当作有限资源来管理:用渐进方式确定 worker 池大小,用指数退避处理限流,用本地缓冲平滑流量,并持续监控动态调整。这样即使遇到上游波动,任务也能稳定推进,而不是一加压就全线失败。