Skip to content

[可靠性] 时间/TTL 纪律审计(过期边界/时钟一致性/窗口矛盾) #2135

Description

@DeliciousBuding

矛盾清单(按风险排序)

F1 [P2] 产品会话 JWT 缺少 clock skew leeway

  • 两个时间量:产品 JWT ParseToken leeway = 0s vs capability token / edge validate leeway = 30s
  • 证据hub-server/internal/jwtutil/jwt.go:97 (ParseToken) 和 :351 (KeyManager.ParseToken) 调用 jwt.ParseWithClaims 时未传 jwt.WithLeeway;而 hub-server/internal/jwtutil/tokendance.go:269edge-server/internal/jwtutil/validate.go:64 均使用 jwt.WithLeeway(30*time.Second)
  • 风险:Hub 与客户端/Edge 时钟偏移 >0s 时,产品会话 JWT 比 capability token 更早被拒;合法用户在 NTP 不同步场景下被踢出会话
  • 修复切片:给 ParseToken / KeyManager.ParseToken 加 jwt.WithLeeway(30*time.Second),与 capability/edge 对齐

F2 [P2] Edge delivery journal retention > run terminal TTL(缓存比数据活得久)

  • 两个时间量:journal retention = 7d vs run terminal cleanup TTL = 24h
  • 证据edge-server/internal/hub/delivery_journal_sqlite.go:280 (DefaultJournalRetention = 7 * 24 * time.Hour) vs edge-server/internal/runcontrol/runcontrol.go:39 (DefaultRunCleanupTerminalTTL = 24 * time.Hour)
  • 风险:run 在 24h 后被清理,但 journal 中引用该 run 的条目保留至 7d;reconciliation/replay 时可能查到孤儿 journal 条目,导致无效重试或错误状态
  • 修复切片:将 journal retention 降至 ≤ run TTL(如 24h),或将 run TTL 提升至 ≥ journal retention;推荐前者(journal 是 run 的派生数据)

F3 [P3] Edge TokenProvider 刷新延迟依赖本地时钟

  • 两个时间量:tokenRefreshLead = 1min vs accessTTL = 15min(lead 占比 6.7%)
  • 证据edge-server/internal/hub/token_provider.go:156 (time.Until(time.Unix(exp, 0)) - tokenRefreshLead),:52 (tokenRefreshLead = time.Minute)
  • 风险time.Until 用本地时钟,exp 由 Hub 签发(Hub 本地时钟)。两节点 NTP 偏移 >1min 时,Edge 可能在 token 已过期后才触发刷新,导致 API 调用失败
  • 修复切片:增加 refresh lead 至 2-3min,或在 refresh 失败时指数退避+立即重试

F4 [P3] WS ReadTimeout 与 pong-miss 检测边界竞争

  • 两个时间量:WSReadTimeout = 60s (2×30s heartbeat) vs pong-miss 检测 ≈ 65s (2×30s + 5s ping timeout)
  • 证据hub-server/internal/ws/conn.go:19 (WSReadTimeout = 2 * config.WSHeartbeatInterval),hub-server/internal/config/constants.go:172,175,179 (Heartbeat=30s, PingTimeout=5s, MaxMissedPongs=2)
  • 风险:完全静默连接上,read timeout 和 pong-miss 几乎同时触发;半开连接上 read timeout 可能先于 pong-miss 关闭连接,跳过 metrics 记录
  • 修复切片:将 WSReadTimeout 调整为 2*Heartbeat + PingTimeout (65s) 或 3*Heartbeat (90s),确保 pong-miss 检测优先触发

边界问题(非矛盾但需注意)

  • JWT 签发/校验均用 time.Now()(本地时钟):hub jwt.go:33,56,276,299,edge token_provider.go:156。无显式 UTC 归一化。当前依赖 Go runtime 默认行为(Unix 时间戳本质是 UTC),但代码意图不明确,未来重构易引入时钟源混用
  • OIDC state 双重过期:Redis TTL=10min + 代码检查=10min (oidc.go:55,149,264)。正确但冗余;代码检查用 time.Since 本地时钟,Redis TTL 是权威

基线

未覆盖面

  • Mobile/Web 前端 token 刷新逻辑(app/ 目录)
  • TokenDance ID 侧 OIDC provider 时钟行为
  • 生产环境 NTP 同步状态实测
  • DB 层 expire_at 字段与时钟源一致性(GORM time.Now() 注入)

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium prioritysize-MMedium effort后端Hub Server、Edge-Hub 通信和后端服务

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions