生产 7:Router 与 SGLang Model Gateway
谁该读这一篇? 要在多个 SGLang worker 前置路由、配置 cache-aware/负载策略,或搭建 PD/gRPC/多模型网关的工程师。 前置阅读:
05-distributed/02-data-parallelism.md。
1. 组件选择
当前仓库有两个相关实现:
| 组件 | 适用场景 | 入口 |
|---|---|---|
experimental/sgl-router |
单模型、静态 URL 或 Kubernetes EndpointSlice | sgl-router Rust binary |
sgl-model-gateway |
多模型(IGW)、PD、HTTP/gRPC、OpenAI 后端、重试/熔断/历史/MCP | sgl-model-gateway 或 python3 -m sglang_router.launch_router |
两者都提供 OpenAI 兼容 API 和 /metrics;不要再使用旧的
pip install sgl-router 或 --worker-weights 示例,安装方式以对应目录的
README/发行包为准。
2. 最小拓扑
Client ─▶ Router/Gateway ──┬─▶ SGLang worker 1
├─▶ SGLang worker 2
└─▶ SGLang worker N
Router 只负责请求路由和可靠性;每个 worker 独立持有 GPU KV cache。cache-aware 信号来自 router 的 prefix tree 或外部 KV indexer,不是把 GPU KV 复制到 router。
3. Experimental sgl-router
从源码构建并运行:
cd sglang/experimental/sgl-router
cargo build --release
./target/release/sgl-router \
--host 0.0.0.0 --port 30000 \
--model-id qwen3 \
--tokenizer-path /models/qwen3/tokenizer.json \
--worker-urls http://10.0.0.1:30000 http://10.0.0.2:30000
也可省略 --tokenizer-path,让 router 根据 --model-id 从 HuggingFace 下载
tokenizer(需要网络和 HF_TOKEN/HF_HOME 配置)。Kubernetes 场景使用
--service-discovery、--service-discovery-namespace 和 --selector;PD 拓扑则
分别使用 --prefill-selector 与 --decode-selector。
外部 KV indexer 示例:
./target/release/sgl-router \
--model-id qwen3 --tokenizer-path /models/qwen3/tokenizer.json \
--worker-urls http://10.0.0.1:30000 http://10.0.0.2:30000 \
--policy cache_aware_zmq \
--kv-indexer-endpoint http://10.0.0.10:50051 \
--kv-indexer-query-timeout-ms 100 \
--kv-indexer-query-max-inflight 32
indexer 查询超时、连接失败或服务端拒绝会返回 503;不会静默切换到另一个
缓存信号。完整参数以 sgl-router --help 为准。
3.1 三类信号不要混淆
当前 worker 能暴露三类不同信息:
- KV placement event 描述 block 存入、移除或清空,供 router/indexer 重建缓存位置;
- 外部 KV indexer 回答“某个 prompt 的 block 在哪些 worker”;
- 可选 runtime-load socket 发布每个 scheduler 的
num_running_reqs、num_waiting_reqs、KV 已用 token、KV 容量和 rank。
第 3 类通过 worker 的 --load-publish-endpoint auto 显式开启,默认关闭,并且要求
同时配置 --kv-events-config。auto 在 KV event 端口范围后为每个 DP rank 分配
load 端口;/server_info 的 kv_events block 会返回
load_endpoint_port_base 与 load_topic。发布周期复用
--load-snapshot-publish-interval,实际部署要给同机 worker 的端口范围留足间隔。
这是一条供进程外 load-aware router 使用的 ZMQ PUB 协议,不等于 bundled
experimental router 的外部 indexer 查询,也不改变上面的 503 语义。消费者必须
显式支持 LoadStat wire format;发布或订阅异常时应回退到自身维护的 in-flight
负载信号,而不能把陈旧 gauge 当成当前 scheduler 状态。
源码:load_publisher.py:72、
server_args.py:1598。
4. SGLang Model Gateway
cd sglang/sgl-model-gateway
cargo build --release
./target/release/sgl-model-gateway \
--worker-urls http://worker1:8000 http://worker2:8000 \
--policy cache_aware
开发或 Python launcher:
python3 -m sglang_router.launch_router \
--worker-urls http://worker1:8000 http://worker2:8000 \
--policy cache_aware
PD 路由可以独立指定 prefill/decode 策略:
./target/release/sgl-model-gateway \
--pd-disaggregation \
--prefill http://prefill1:30001 9001 \
--decode http://decode1:30011 \
--policy cache_aware --prefill-policy cache_aware --decode-policy power_of_two
多模型 inference gateway(IGW)通过 worker registry 动态登记:
./target/release/sgl-model-gateway --enable-igw --policy cache_aware
curl -X POST http://localhost:30000/workers \
-H 'Content-Type: application/json' \
-d '{"url":"http://worker-a:8000","model_id":"qwen3","priority":10}'
curl http://localhost:30000/workers
5. 路由策略
Model Gateway 当前支持:
| 策略 | 行为 | 适合 |
|---|---|---|
random |
均匀随机选择 | 基线/测试 |
round_robin |
轮询 | 无缓存收益的简单服务 |
cache_aware |
prefix tree + 阈值做重复 prompt 复用,并在失衡时平衡 | 共享 system prompt |
power_of_two |
随机抽两个 worker,选负载较低者 | 负载波动明显 |
bucket |
按 bucket/DP 亲和性选择 | 需要固定分组 |
cache_aware 是近似的路由决策:真实 KV 仍在 worker GPU,树状态会变化,
因此它不是一致性或正确性保证。可调参数包括 --cache-threshold、
--balance-abs-threshold、--balance-rel-threshold、--eviction-interval 和
--max-tree-size。
6. 健康、重试与故障切换
Gateway 提供 /liveness、/readiness、/health、/health_generate;readiness
会检查健康 worker,PD 模式还要检查 prefill/decode 配对。生产探针应给 CUDA
Graph capture 和模型加载留足启动时间。
Gateway 的数据面包含每 worker circuit breaker、指数退避重试(带 jitter)、
token bucket 与可选 FIFO 请求队列,以及 PD worker 的 /flush_cache 管理。
请求中途失败时 router 不会无条件 replay 有状态请求;客户端仍应使用带 jitter
的有限重试,并保证幂等键/会话语义。
7. API 与观测
常用接口包括 /v1/chat/completions、/v1/responses、/v1/embeddings、
/v1/rerank、/v1/classify,以及 /v1/tokenize//v1/detokenize。gRPC
模式在 router 本地完成 tokenizer、reasoning parser 和 tool parser,再将流式
请求发送到 SRT gRPC worker。
启用 Prometheus(gateway 默认监听 0.0.0.0:29000):
./target/release/sgl-model-gateway \
--worker-urls http://worker1:8000 \
--prometheus-host 0.0.0.0 --prometheus-port 29000
重点关注 smg_router_*、smg_worker_*、smg_worker_cb_*、
smg_worker_retries_* 和 smg_discovery_*;SGLang worker 自身的 sglang:*
指标见 03-monitoring.md。
8. 排查清单
| 现象 | 检查 |
|---|---|
| cache-aware 命中下降 | eviction、tree 大小、max-tree-size,必要时切 power_of_two |
| 流量长期倾斜 | cache-aware 的倾斜可能是预期;比较 worker load,再调 balance 阈值 |
| worker 被摘除 | /health、熔断器状态、连续失败次数和连接超时 |
| PD 请求 503 | prefill/decode 是否都 ready,bootstrap port 和 selector 是否匹配 |
| gRPC 请求失败 | tokenizer/model path、reasoning/tool parser 与 worker 能力是否一致 |
| router CPU 高 | 请求量、tree 大小和 discovery 刷新频率,增加 gateway 副本 |
9. 小结
- 单模型静态路由可用 experimental
sgl-router;多模型、PD、gRPC 和可靠性能力优先使用sgl-model-gateway。 cache_aware使用 prefix/tree 信号做路由近似,不共享 GPU KV,也不是 Bloom filter API 的承诺。- 灰度应在 Kubernetes/service mesh 或独立 worker pool 层完成;当前 CLI 没有可依赖的
--worker-weights合同。 - 健康检查、熔断、重试、Prometheus 和 OpenTelemetry 应作为生产配置的一部分。
10. 自检
- Router 是否持有 RadixCache 的 KV?
不持有。KV 在 worker 的设备/层级缓存中;router 只维护 prefix/tree 或 indexer 查询结果。
- 外部 KV indexer 查询失败时会发生什么?
cache_aware_zmq 会将失败、超时或服务端拒绝报告为 503,不会静默使用过期或不同来源的信号。
- 什么时候选
power_of_two而不是cache_aware?
prompt 重复率低、worker 负载差异大,或缓存树维护成本超过收益时,power_of_two 通常更合适。
11. 下一步
08-multi-tenant.md— 多租户隔离。09-versioning.md— 版本灰度与回滚。- 上游说明:
sgl-router/README.md、sgl-model-gateway/README.md。