Skip to content

Feature: 支持为每个供应商配置独立的 Session TTL #603

@sususu98

Description

@sususu98

功能需求

允许每个供应商配置独立的 sessionTtl,而不是使用全局的 SESSION_TTL 环境变量。

背景

目前,粘性会话的 TTL 由单一的全局环境变量 SESSION_TTL 控制(默认 300 秒)。所有供应商共享相同的会话过期时间。

使用场景:不同供应商可能有不同的特性:

  • 某些供应商更稳定,可以使用更长的会话绑定时间(如 600s)
  • 某些供应商可能需要更短的 TTL 以便更快故障转移(如 120s)

实际痛点

当 Antigravity 和 Max 使用相同优先级时,默认 5 分钟的 TTL 可能会导致频繁切换供应商,产生大量 400 错误。理想情况下,我们希望为这些高优先级供应商设置更长的 TTL(如 30 分钟)来保持会话稳定。

但是,如果调整全局 SESSION_TTL,会导致低优先级的账户(如备用供应商)也被长时间绑定,这样会多花很多钱(因为无法及时切换回高优先级供应商)。

期望效果

  • 高优先级供应商:sessionTtl = 1800(30 分钟),保持会话稳定,减少 400 错误
  • 低优先级供应商:sessionTtl = 300(5 分钟)或更短,尽快释放以便切回高优先级

建议方案

1. 数据库 Schema 变更

providers 表中添加新字段:

ALTER TABLE providers ADD COLUMN session_ttl INTEGER;
-- NULL 表示使用全局默认值 (env.SESSION_TTL 或 300s)

2. SessionManager 改造

添加 TTL 解析方法:

static resolveSessionTtl(providerTtl: number | null | undefined): number {
  const rawValue = providerTtl ?? SessionManager.SESSION_TTL;
  // 限制在 [60, 3600] 秒范围内
  return Math.max(60, Math.min(rawValue, 3600));
}

修改现有方法以接受可选的 sessionTtl 参数(约 18 个方法需要修改)。

3. 管理界面

在供应商配置表单中添加 Session TTL 输入框。

需要修改的文件

类别 文件 复杂度
数据库 Schema src/drizzle/schema.ts
类型定义 src/types/provider.ts
Repository src/repository/provider.ts
SessionManager src/lib/session-manager.ts
Proxy 流程 src/app/v1/_lib/proxy/session.ts, forwarder.ts
Admin UI src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
i18n messages/*/settings/providers/form/sections.json (5 种语言)

预计修改约 15 个文件

边界情况处理

  1. 熔断器故障转移:从供应商 A (TTL=600s) 切换到供应商 B (TTL=300s) 时,使用新供应商的 TTL
  2. 优先级升级:升级到更高优先级供应商时,使用新供应商的 TTL
  3. 并发请求:首次绑定获胜(现有 SET NX 逻辑),TTL 跟随首次绑定的供应商

验收标准

  • 供应商可以在管理界面配置 sessionTtl(范围:60-3600 秒)
  • null 回退到全局 SESSION_TTL(向后兼容)
  • Redis key 使用供应商特定的 TTL
  • resolveSessionTtl 方法的单元测试
  • 支持全部 5 种语言的 i18n

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions