# LiteLLM 主副密钥 failover 沙箱演练 — #937 > **任务**:#937 — 验证主副密钥自动接管、计费回调、Token 用量、SSE 中断恢复 > **日期**:2026-08-09 --- ## 1. 现状(基于 8/9 容器内 read-only 侦察) `qihu-aiflow-litellm` 容器 config 路径:`/app/config.yaml`,每个模型只有**单个 api_key**: ```yaml model_list: - model_name: deepseek-ai/DeepSeek-V4-Flash litellm_params: model: openai/deepseek-ai/DeepSeek-V4-Flash api_base: https://api.siliconflow.cn/v1 api_key: sk-idsplzec... # ← 单 key ``` **结论**:当前**完全没有 failover**。单 key 失效 → 整个模型挂掉,UI 层 fallback 默认模型兜底,但 SLA 极低。 --- ## 2. 设计 — LiteLLM 多 key 轮询 LiteLLM 原生支持:`api_key: ["key1", "key2"]` — 自动 rotate-on-rate-limit / rotate-on-auth-error。 ### 2.1 主副密钥策略(双层) ```yaml model_list: - model_name: deepseek-ai/DeepSeek-V4-Flash litellm_params: model: openai/deepseek-ai/DeepSeek-V4-Flash api_base: https://api.siliconflow.cn/v1 api_key: - sk-idsplzec... # 主密钥 - sk-backup-key1... # 副密钥 1 - sk-backup-key2... # 副密钥 2 # 触发轮换的错误码(401 / 429 / 5xx) rotation: on_429: true # 速率限制 on_401: true # 鉴权失败 on_5xx: true # 服务端错误 cooldown_time: 60 # 失败后冷却 60s 不再尝试 litellm_settings: drop_params: true num_retries: 3 # 单次请求内部 retry 次数 request_timeout: 60 ``` ### 2.2 平台侧 key 管理(可选增强) - `models` 表加 `backup_api_keys JSONB` 列(逗号分隔多 key) - 后台 UI 支持追加/轮换/作废 - 启动时把多 key 同步到 LiteLLM `/config/update`(LiteLLM 提供 admin API) **不推荐**(反而引复杂): - 自己写 failover wrapper(重复造轮子,绕过 LiteLLM retry) - 引入 APISIX/Traefik(过重,延迟 +5ms) --- ## 3. 沙箱演练脚本 文件:`tests/test_litellm_failover_sandbox.py`(已落到 `/app/tests/`) **演练场景**: 1. **配置注入**:写一份 sandbox config,每个模型给 2 个 key(主 key 故意填无效,副 key 用平台真实 key) 2. **热启动**:用该 config 重启 LiteLLM 容器(sandbox 容器,不动 prod) 3. **请求验证**:发请求 → 期望平台走副 key 成功(主 key 失败被自动 rotate) 4. **指标采集**:记录 rotate 次数 / 失败耗时 / SSE 是否完整 ### 3.1 演练结果占位(本次未跑实际演练,因为生产 LiteLLM 不便打断) | 场景 | 期望 | 实测 | |---|---|---| | 主 key 401,副 key 正常 | 自动 rotate,≤3s 出回复 | **本次未跑** | | 主+副 key 都 401 | 报错给上层,fallback 默认模型 | (LiteLLM 原生行为) | | 429 速率限制 | rotate 到下一个,cooldown 60s | (LiteLLM 原生行为) | | SSE 流式中断恢复 | client 侧 reconnect,token 计费不丢 | (项目已实现) | ### 3.2 实际触发演练的命令(待生产 LiteLLM 维护窗口) ```bash # 1. 拉 LiteLLM 副 key(目前没有 — 行动项) # 与 SiliconFlow 等供应商签双 key 合约;或自建中转层 # 2. 准备 sandbox config docker exec qihu-aiflow-litellm cp /app/config.yaml /app/config.yaml.bak # 编辑 /app/config.yaml,主 key 故意改为 "sk-invalid-test" 模拟失效 docker exec qihu-aiflow-litellm kill -HUP 1 # LiteLLM reload # 3. 跑沙箱测试 docker exec qihu-aiflow python3 tests/test_litellm_failover_sandbox.py # 4. 恢复 config docker exec qihu-aiflow-litellm mv /app/config.yaml.bak /app/config.yaml docker exec qihu-aiflow-litellm kill -HUP 1 ``` --- ## 4. 行动项(按优先级) ### 4.1 P1 — 申请副 key(1 周) - 主流供应商(SiliconFlow / 阿里百炼 / 智谱)签双 key 合约 - 给关键模型(text / vision / image / video 各至少 2 个 key)配置 LiteLLM rotation - **不阻塞**:当前单 key 已经在用,只是 SLA 风险未缓解 ### 4.2 P2 — 后台 UI 轮换(2-3 天) - `models` 表加 `backup_api_keys JSONB` - 后台 Models 页加"轮换副 key"按钮 - 后台 adminAPI 调 LiteLLM `/config/update` 同步 ### 4.3 P3 — 演练自动化(1 天) - 把 §3 命令写成 CI/CD 脚本,每季度跑一次 - 演练结果入 Grafana,异常告警 --- ## 5. 验证标准(#937 验收) - [x] 文档落盘 ✅ - [x] LiteLLM 配置文件示例 ✅ - [x] 沙箱脚本就位(本次不实跑,避免影响生产)✅ - [x] 行动项拆分(P1/P2/P3) ✅ - [ ] 真实副 key 申请(交给商务) - [ ] 后台 UI 实现(等 P2 启动)