Skip to content

fix(scheduler): session_hash sticky 引入健康度逃逸,慢账号不再独占用户会话#2872

Open
wucm667 wants to merge 1 commit into
Wei-Shaw:mainfrom
wucm667:fix/scheduler-sticky-health-escape
Open

fix(scheduler): session_hash sticky 引入健康度逃逸,慢账号不再独占用户会话#2872
wucm667 wants to merge 1 commit into
Wei-Shaw:mainfrom
wucm667:fix/scheduler-sticky-health-escape

Conversation

@wucm667
Copy link
Copy Markdown
Contributor

@wucm667 wucm667 commented May 29, 2026

背景

OpenAI 高级调度器当前的调度层次是 previous_response_id -> session_hash sticky -> load balance。

其中 previous_response_id 需要保持硬粘性以兼容上游 response 历史,这条路径本 PR 不做改动。

问题出在 session_hash sticky:命中后会直接返回 sticky 账号,既不检查运行时健康度,也会在账号并发已满时继续返回该账号的 WaitPlan。当某个账号的 TTFT 明显恶化、错误率上升,或已经满并发时,用户会被长期绑在这个慢/降级账号上,无法自然逃逸到更健康的账号。

改动

  1. selectBySessionHash(...) 命中 sticky 账号后、真正返回前,接入已有运行时统计 snapshot(accountID),增加 session sticky 健康度门控。
  2. 新增可回退配置 gateway.openai_scheduler
    • sticky_escape_enabled:默认 true,运维可设为 false 一键回到旧行为。
    • sticky_escape_ttft_ms:默认 15000
    • sticky_escape_error_rate:默认 0.5
  3. 满足以下任一条件时,本次请求跳过 sticky,直接落入下一层 load balance:
    • hasTTFT && ttft > sticky_escape_ttft_ms
    • errorRate > sticky_escape_error_rate
    • sticky 账号当前并发已满
  4. 逃逸时记录 sticky_escape_triggered 日志,带上 account_idreasonerror_ratettft,便于运维定位。
  5. 逃逸后不清除 session_hash -> account_id 持久绑定,也不在本次 load balance 成功后改写该绑定,只做“本次跳过”。
  6. previous_response_id 路径保持不变,load balance 打分逻辑保持不变。
  7. 配置加载时对新键提供默认回填,保证旧配置文件缺失该段时仍默认启用;显式配置非法值时继续严格校验。

默认阈值选择理由:

  • 15000ms 的 TTFT 阈值足够宽松,不会因轻微波动就频繁逃逸,但能及时释放被几十秒级长尾卡住的会话。
  • 0.5 的错误率阈值意味着 EWMA 需达到明显劣化才触发,不会对短暂抖动过敏。

性能影响:

  • snapshot() 仅执行 atomic load + math.Float64frombits,属于纳秒级读取,不引入额外性能顾虑。

兼容性:

  • previous_response_id 的硬粘性路径完全不变。
  • sticky_escape_enabled=false 时可完整回退到旧行为。

测试

已执行:

  • cd backend && go test -tags=unit ./internal/service/... -run OpenAIAccountScheduler
  • cd backend && go test -tags=unit ./...
  • cd backend && golangci-lint run ./...

新增覆盖:

  • sticky 账号 TTFT 低于阈值时继续命中 sticky
  • sticky 账号 TTFT 高于阈值时逃逸到下一层调度
  • sticky 账号 errorRate 高于阈值时逃逸
  • sticky 账号并发满时不再返回 sticky WaitPlan,而是逃逸
  • sticky_escape_enabled=false 时保持旧行为
  • 阈值边界值(等于阈值)不触发逃逸

未发现与“sticky 健康度逃逸 / session_hash sticky escape”同方向的并发 PR。

Fixes #2859

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenAI 高级调度器的 sticky 账号可能无法逃逸,导致慢账号持续影响用户体验

1 participant