Skip to content

Load Balancer + Token Tracking + Rate Limiter 设计 #271

@milo-oaklight

Description

@milo-oaklight

背景

目前 rosetta 不允许同名 model 存在,但实际场景中同一个 model 会有多个 provider(如 claude-opus-4 同时走 Anthropic direct 和 Bedrock)。需要引入 load balancer 解决路由问题,同时配套 token tracking 和 rate limiter。


一、Load Balancer(优先落地)

核心变化: model name 从唯一标识变成逻辑名,1:1 映射改成 1:N,同一个逻辑 model 下挂多个 backend。

方案:

  • 配置层:同名 model 的多个 provider entry 收进列表,不再互相覆盖
  • 路由策略:初期 priority-based failover(主备),后续可加 least-outstanding-requests 或 capacity-aware
  • 健康管理:被动标记,连续 N 次 429/5xx 暂时摘除,过段时间恢复探测。不需要 active health check
  • Failover:单个 backend 失败时自动尝试列表中下一个,控制 retry 次数
  • 直接在 rosetta 内实现,不放 zerodep

二、Token Tracking

数据来源: Converter 转换 response 到 IR 时 usage 已标准化,proxy 层直接从 IR 读取,不需要单独的提取逻辑。

两条并行路径,互不依赖,同一个请求完成点写入:

  • SQLite per-request record(source of truth)— 每个请求完成时 INSERT 一条,字段:timestamp, consumer_key, logical_model, provider, backend_id, input_tokens, output_tokens, latency_ms, status。用于审计、成本分析、路由决策追溯
  • 内存 counter(实时决策)— 按 (consumer_key, model, provider) 维度聚合,rate limiter 和 load balancer 直接读

完整链路:

provider response → converter → IR(含 usage)→ proxy 读 IR.usage + 路由上下文 → 写 SQLite record + 更新内存 counter

Streaming: 从最后一个 chunk 的 usage 拿,拿不到时 fallback estimation 标 estimated=true

三、Rate Limiter(后续)

  • 先只做 RPM,per-key per-provider
  • Token bucket,内存维护
  • TPM 等需要时再加维度
  • 在内存 counter 基础上加一层判断即可

落地顺序

  1. Load Balancer — 解决同名 model 多 provider 路由
  2. Token Tracking — 两条路径一起做
  3. Rate Limiter — load balancer 和 token tracking 稳定后再叠加

设计原则

  • 不用 log file 做 source of truth,用 SQLite structured record + 内存 counter
  • Converter 只做本职(格式转换),usage 是 IR 的自然产物
  • Proxy 负责补路由上下文和写入

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureArchitectural improvementsenhancementNew feature or requestgatewayGateway proxy features and improvements

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions