feat(routing): 会话首请求上游竞速——等权组内择快并绑定亲和
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 42/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Tranquilla
- Stack tecnologico
- typescript
- Ambito
- api, backend, performance
Direzione di ricerca
Inizia da session-affinity.ts e traccia i percorsi esistenti per la selezione ponderata degli upstream, l’ammissione della concorrenza, il logging delle richieste e failoverHistory. Verifica come vengono gestiti i mancati riscontri dell’affinità e le risposte al primo byte, quindi definisci test per le corse con priorità uguale e peso uguale, il vincolo al vincitore, gli abort dei perdenti, il logging e lo switch globale; il lavoro è concluso quando le proporzioni di selezione esistenti rimangono invariate al di fuori dei mancati riscontri dell’affinità idonei.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
背景
当前上游选择完全由人工配置驱动:候选集经能力匹配、密钥授权、健康/熔断过滤、并发准入后,按 priority 分层、层内按 weight 加权随机选一个。系统不感知上游的实时快慢,个别请求卡在慢上游时只能等超时后 failover。
请求日志中已有完整的耗时数据,但仅用于事后报表,未参与选路决策。
方案:首请求竞速 + 亲和绑定
利用现有会话亲和性机制(session-affinity.ts,绑定键为 (apiKeyId, capability, sessionId))的 miss/hit 分叉作为竞速触发点:
请求进来 → 查亲和性
├─ 命中 → 直连绑定上游(会话内绝大多数请求,零额外成本)
└─ 未命中 → N 路并发竞速 → 胜者响应并写入绑定 → 本会话后续直连胜者
胜者是实测选出的“此刻对该会话最快的上游”,等于每个会话开头免费做了一次真实探测,且后续请求命中胜者的 prompt cache。
设计决策
| 决策点 | 结论 |
|---|---|
| 触发时机 | 亲和性 miss 且能提取出 sessionId(提不出的请求走原有选路,防止一次性调用每次都竞速) |
| 参赛资格 | 先按现有逻辑加权随机选出“种子”,与种子同优先级且同权重的候选构成竞速组 |
| 参赛人数 | 默认 2,上限 3,组内随机抽取;组内只有种子自身时不竞速,直连 |
| 胜负判定 | 首字节到达且状态码非 5xx;输家立即 abort 流 |
| 绑定 | 胜者写入现有亲和性绑定(TTL 语义不变:滑动 5 分钟 / 绝对 30 分钟) |
| 开关 | 全局开关,默认开启 |
| 记录 | 全部参赛路计入请求日志与计费快照(复用 failoverHistory 结构,竞速≈并行版 failover 首跳) |
参赛资格的语义依据
priority 表达“我更想用谁”,weight 表达“我要谁多承担”——竞速若跨层或跨权重,会用“谁快用谁”推翻这些人工意志。同优先级 + 同权重是配置中唯一“毫无偏好声明”的等价组,现有实现对它们用纯随机;把纯随机换成实测竞速,是不覆盖任何人工配置的升级。
由此天然获得细粒度控制面:想让哪些上游竞速就配成等权同级;不想让某个贵上游参赛,挪 1 点权重即可退出。无需逐上游开关与新增 UI。
种子选组机制保证跨组流量分配比例完全不变(weight 语义原样保留),竞速只发生在等权组内部。
成本与已知取舍
- 竞速不是严格“每会话一次”:亲和绑定 30 分钟到期或空闲超 5 分钟失效后会重新竞速,频率仍然很低。
- 输家上游照付首轮输入 token 费用(或消耗订阅账号一次请求额度),故 N 默认 2、上限 3。
- 等权组内 weight 的分流作用会部分失效(谁快谁赢)。存在一定自平衡:胜者负载升高变慢后开始输,流量自然溢出。额度型限制(如订阅 5 小时窗)不体现在延迟上,耗尽报错后由现有 failover 兜住。
- 已把多个按量付费上游配成等权的存量用户,升级后首轮 token 费会随竞速翻倍,需在发版说明中告知(默认开启的告知义务)。
边界与注意点
- 竞速期间并发槽位短暂占用 N 个,需与队列准入机制正确交互(并发满的候选本就已被过滤出候选集)。
- 胜负判定后输家 abort 必须及时,避免继续产生输出 token。
- 下游响应与错误体不得携带上游身份信息(沿用现有约束)。
不做的事
- 全量竞速(每请求 N 路):成本 ×N,不做;本方案阈值语义上是其安全子集。
- 对冲请求(hedged requests,绑定上游中途卡住时补发备胎):与竞速互补,另行考虑。
- 逐上游“参与竞速”开关与 UI:等权同级配置已是控制面,暂不需要。
- Lingua principale
- TypeScript
- Stelle
- 4
- Fork
- 0
- Merge medio
- 10m
- PR unite (30g)
- 3
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Ha un modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di g1331/AutoRouter
-
feature
Difficoltà 5/5 Più di una settimana Idoneità per principianti 45/100
g1331/AutoRouter#236 ·
I maintainer di solito rispondono entro 1 giorno
-
feature
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
g1331/AutoRouter#235 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di g1331/AutoRouter
Issue simili
-
Difficoltà 1/5 1-3 ore Idoneità per principianti 86/100
g1331/phantom-circuit#93 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
compiler
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
HerringtonDarkholme/hd-lang#1699 ·
I maintainer di solito rispondono entro 1 giorno
-
account bug communication lecture
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno