Prhub

#28742 [router] Raise chat body cap to 5 MiB for long contexts

原始 PR 作者 Kangyan-Zhou 合并时间 2026-06-20 06:50 文件变更 3 提交数 1 评论 0 代码增减 +19 / -16

执行摘要

路由器请求体上限 1 MiB 提升至 5 MiB

实验性路由器将 /v1/chat/completions 请求体限制在 1 MiB,但对于约百万 token 的上下文,JSON 编码后超过 1 MiB,导致合法长上下文请求在到达 worker 前被拒绝(413 PAYLOAD_TOO_LARGE)。

该 PR 设计清晰、改动集中,值得精读以了解路由器限流和可观测性配置。特别是测试改用对配置常量的引用而非硬编码数字的做法值得学习。

讨论亮点

无人工 review 评论,仅 Gemini Code Assist 自动评论确认变更合理且测试通过。

实现拆解

  1. 提升请求体上限:在 experimental/sgl-router/src/server/routes/chat.rs 中,将 MAX_CHAT_BODY_BYTES1 << 20(1 MiB)改为 5 << 20(5 MiB)。5 MiB 约等于 125 万 token(按 4 bytes/token 估算),覆盖 ~1M token 上下文。该限制由 axum 的 DefaultBodyLimit layer 在 handler 执行前强制检查。
  2. 扩展直方图桶边界:在 experimental/sgl-router/src/server/metrics.rs 中,OVERLAP_BLOCKS_BUCKETS 从最高 1000 扩展到 2000、4000、8000,避免长上下文场景下高 overlap block 数量全部落入 +Inf 桶,保持可观测性。
  3. 更新单元测试:在 experimental/sgl-router/tests/proxy/chat_routing.rs 中,oversized_request_body_returns_413 测试改用 MAX_CHAT_BODY_BYTES + 1 而非硬编码的 2 MiB,使测试自动跟踪配置变化。同时更新 histogram_plus_inf_bucket_catches_overflow 测试,将观测值从 1001 改为 8001,验证新桶边界。
文件 模块 状态 重要度
experimental/sgl-router/src/server/routes/chat.rs 路由器 modified 6.07
experimental/sgl-router/src/server/metrics.rs 路由器 modified 6.16
experimental/sgl-router/tests/proxy/chat_routing.rs Chat 路由 modified 4.32

关键源码片段

experimental/sgl-router/src/server/routes/chat.rs entrypoint

核心变更:将请求体上限从 1 MiB 提升到 5 MiB,更新文档注释。

/// Per-route body-size cap on `/v1/chat/completions`. 5 MiB accommodates a
/// long context — a ~1 M-token context tokenized as JSON fits under this —
/// while preventing a hostile client from forcing the router to
/// heap-allocate hundreds of MiB before forwarding. The cap is wired in
/// `crate::server::app::build_router` as a route-level `DefaultBodyLimit`
/// layer; axum's `Bytes` extractor enforces it and returns 413
/// PAYLOAD_TOO_LARGE before this handler runs.
pub const MAX_CHAT_BODY_BYTES: usize = 5 << 20; // 之前是 1 << 20 (1 MiB)
experimental/sgl-router/src/server/metrics.rs entrypoint

扩展 overlap_blocks 直方图桶边界至 8000,保持长上下文场景的可观测性。更新文档注释和单元测试。

/// Histogram bucket upper bounds for `sgl_router_overlap_blocks`. Blocks are
/// 32–64 tokens each, and the `MAX_CHAT_BODY_BYTES` cap bounds context length —
/// putting the practical ceiling for a maximum-length context in the low tens
/// of thousands of blocks. The ladder spans 0 → ~8k blocks at the resolution
/// worth charting; the `+Inf` bucket catches the longer-context tail beyond
/// 8000.
const OVERLAP_BLOCKS_BUCKETS: &[f64] = &[
    // 桶边界从 1000 扩展到 8000,新增 2000, 4000, 8000
    0.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1000.0, 2000.0, 4000.0, 8000.0,
];

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  • 内存风险:5 MiB 的请求体仍由路由器的 Bytes 提取器完整缓冲到内存中,但 5 MiB 是合理上限,不会导致 OOM。
  • 性能风险:更大的请求体可能略微增加序列化和开销,但影响可忽略,因为路由器只做轻量 probe 解析。
  • 兼容性:向后兼容 —— 旧版客户端仍可正常请求。
  • 用户:支持超长上下文请求(如文档分析、长对话),消除此前 1 MiB 限制导致的拒绝。
  • 系统:路由器内存使用略微增加,但受 5 MiB 上限保护。
  • 团队:需要确保其他组件(如 worker 端)也能处理更长上下文,避免出现新的瓶颈。
内存影响 测试覆盖合理

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论