核心概念
理解下面几个对象,基本就理解了 Sub2API 的配置方式。
用户
用户是消费 API 配额的主体,拥有余额、并发上限、订阅、平台配额和一个或多个 API Key。管理员也属于用户,但具有后台管理权限。
API Key
API Key 是客户端访问网关的凭证。它可以绑定分组,并配置状态、倍率、额度或速率限制。
客户端通常只接触 Sub2API 生成的 API Key,不应获得上游账号的真实凭证。
账号
账号代表一个可访问上游模型平台的凭证,例如:
- Anthropic API Key 或 OAuth 账号。
- OpenAI API Key、Codex OAuth 账号或兼容上游。
- Gemini OAuth、AI Studio API Key 或 Vertex Service Account。
- AWS Bedrock 凭证。
账号包含平台、类型、凭证、代理、并发、优先级、可调度状态、模型限制和上游特定参数。
分组
分组连接“用户侧 API Key”和“上游账号池”。一个分组通常定义:
- 目标平台。
- 可以使用的账号。
- 支持或限制的模型。
- 模型映射规则。
- 用户计费倍率和渠道定价。
- Claude Code、图片、视频等功能开关。
当 API Key 绑定到某个分组后,请求会在该分组允许的账号范围内调度。
渠道
渠道是提供给用户查看和选择的服务能力描述,通常包含平台、模型、价格和可用状态。渠道偏向产品展示,分组更接近实际调度与计费边界。
粘性会话
粘性会话让同一段对话尽量持续使用同一个上游账号。系统会综合请求 metadata、客户端信息和 API Key 等生成会话标识,再把会话与账号绑定缓存到 Redis。
粘性不是绝对绑定:账号不可用、限流、模型不支持或触发故障切换时,系统可以选择新账号。
余额、订阅和配额
标准模式下,请求在访问上游前会检查用户是否具备计费资格:
- 有可用订阅额度;或
- 有可用余额;并且
- 没有超过 API Key 或用户平台配额。
请求完成后,系统根据上游 usage、模型价格、服务等级、缓存 Token、图片或视频规格计算费用并记录用量。
并发与速率限制
并发控制回答“当前有多少请求正在执行”,速率限制回答“一个时间窗口里已经使用多少”。两者都会使用 Redis,但用途不同:
| 机制 | 典型维度 | 超限后的行为 |
|---|---|---|
| 并发槽位 | 用户、API Key、账号 | 等待或拒绝 |
| RPM | 用户、API Key、账号、模型 | 冷却或切换账号 |
| Token/费用窗口 | 5 小时、日、周、月 | 拒绝或等待窗口重置 |
| 上游错误限流 | 账号、模型 | 临时取消调度或故障切换 |
代理
代理可以绑定到账号,用于固定出口、网络隔离或访问特定上游。生产环境应优先为账号显式绑定经过验证的代理,不要依赖“代理失败后自动直连”,否则可能泄漏真实出口 IP。
对象关系总图
User
├── API Key ───────────────▶ Group
│ ├── Account Group ──▶ Account ──▶ Proxy
│ ├── Channel
│ └── Subscription Plan
├── User Subscription ──────▶ Group
├── User Platform Quota
├── Payment Order
└── Usage Log
├── API Key
├── Group
├── Account
└── Subscription(可选)其中“用户 → API Key → 分组 → 账号池”是请求路由主链;“用户 → 订阅 → 分组”是权益链;Usage Log 把两条链在请求完成后关联起来。
用户如何获得分组权限
分组可分为普通分组和独占分组:
- 普通分组可以按平台和系统规则向用户开放。
- 独占分组通常需要通过
user_allowed_groups显式授权。 - API Key 绑定分组时,还会检查用户是否允许使用该分组。
- 用户的分组倍率可以覆盖或叠加分组默认定价逻辑。
因此“后台能看到分组”不等于“某个用户的 API Key 可以绑定它”。排查权限问题时,要同时看分组状态、用户授权和 API Key 当前绑定。
账号状态与可调度状态不是一回事
账号是否能被选中通常同时取决于:
status是否 active。schedulable是否为 true。- 是否过期或启用了到期自动暂停。
- 是否处于临时限流、过载、401/403 冷却。
- 是否支持目标模型和请求类型。
- 账号并发是否已满。
- 分组、模型路由和隐私状态是否允许。
账号页面显示“正常”但请求仍未选中,往往是临时运行状态或模型能力过滤导致的。
分组同时承担路由和产品规则
分组不是简单标签,它可能配置:
- 平台、订阅类型、日/周/月额度。
- 文本、图片、批量图片、视频倍率和定价。
- Claude Code only 与 fallback group。
- 模型路由、默认映射、支持模型范围。
- OpenAI Messages dispatch 和 OAuth only。
- RPM 上限、高峰倍率和展示排序。
这也是为什么修改分组属于高风险操作:它可能同时改变可用账号、客户端兼容、用户价格和订阅权益。
渠道、分组和账号的区别
| 对象 | 面向谁 | 回答的问题 |
|---|---|---|
| 账号 | 管理员与调度器 | “用哪个真实凭证访问上游?” |
| 分组 | 权限、调度与计费 | “这类用户可以使用哪些账号,以什么规则计费?” |
| 渠道 | 用户与产品展示 | “平台对外提供什么能力、模型、价格和状态?” |
小规模内部部署可以主要使用账号和分组;公开运营时,渠道能提供更清晰的用户侧产品表达。
三种额度不要混淆
用户余额
余额是通用货币账户。请求没有可用订阅或按余额模式结算时,从余额扣除费用。冻结余额用于批量图片等需要预占费用的异步任务。
订阅额度
订阅绑定用户与分组,拥有起止时间和日/周/月窗口用量。窗口开始时间与用量一起保存,达到上限后等待对应窗口重置。
API Key 配额
API Key 可设置总 quota,以及 5 小时、1 天、7 天费用窗口。它是对某个具体客户端凭证的附加限制,不会增加用户真实余额或订阅额度。
请求需要同时满足适用的多层限制,而不是任选一层通过即可。
费用中的倍率
最终费用可能由多个因素组成:
模型基础价格
× 分组倍率
× 用户分组倍率(如配置)
× 高峰时段倍率(如启用)
× 图片/视频独立倍率(按请求类型)
× 批量任务折扣(如适用)账号自身的 rate_multiplier 更偏向平台成本核算,不等同于用户侧分组倍率。配置时要先明确是在计算“向用户扣多少”还是“这个账号实际成本多少”。
会话、Previous Response 与账号绑定
不同客户端提供的会话信号不同:
- Anthropic metadata user ID。
- 客户端传入的 session ID。
- Codex
previous_response_id。 - API Key、IP 和 User-Agent 的组合。
系统对这些信号做标准化并写入 Redis TTL 绑定。OpenAI Responses WebSocket 还可能维护响应 ID 与连接复用关系,因此简单删除粘性缓存可能影响后续 previous response 请求。
软删除
用户、API Key、账号、分组等实体大量采用软删除:数据写入 deleted_at,普通查询不再返回,但历史用量和审计关系可以保留。
软删除带来两个注意点:
- 唯一索引通常只约束未删除记录,因此删除后可以复用名称或邮箱。
- 直接写 SQL 时必须注意
deleted_at IS NULL,否则可能读到历史对象。
配置优先级
应用配置一般遵循:
环境变量 > config.yaml > 内置默认值环境变量通过把配置路径中的点替换为下划线得到,例如:
database.max_open_conns
↓
DATABASE_MAX_OPEN_CONNS管理后台还存在存储在数据库中的运行时设置。部署级硬开关与后台设置同时存在时,需要区分“重启后加载的配置”和“后台立即生效的配置”。