SGLang 模型网关#
SGLang 模型网关是为大规模 LLM 部署设计的高性能模型路由网关。它实现了工作节点生命周期的集中管理,平衡了跨异构协议(HTTP, gRPC, OpenAI 兼容)的流量,并为历史记录存储、MCP 工具调用和隐私敏感型工作流提供了企业级控制。该网关针对 SGLang 服务运行时进行了深度优化,但也能路由到任何兼容 OpenAI 的后端。
目录#
概述#
统一控制面:用于在异构模型集群中注册、监控和编排常规、预填充(prefill)及解码(decode)工作节点。
多协议数据面:通过共享的可靠性原语,在 HTTP、PD(预填充/解码)、gRPC 以及兼容 OpenAI 的后端之间路由流量。
业界首创的 gRPC 流水线:具备原生 Rust 分词、推理解析器和工具调用执行功能,支持高吞吐、OpenAI 兼容的服务;同时支持单阶段和 PD 拓扑结构。
推理网关模式 (
--enable-igw):动态实例化多个路由栈(HTTP 常规/PD, gRPC),并为多租户部署应用针对每个模型的策略。对话与响应连接器:在路由层集中存储聊天历史,使相同的上下文可在不同模型和 MCP 循环中复用,且不会将数据泄露给上游供应商(支持内存、none、Oracle ATP、PostgreSQL)。
企业级隐私:Agent 化的多轮对话
/v1/responses、原生 MCP 客户端(STDIO/HTTP/SSE/Streamable)以及历史存储均在网关边界内运行。核心可靠性:带抖动的重试、工作节点级的熔断器、带排队的令牌桶限流、后台健康检查以及缓存感知的负载监控。
全面的可观测性:40 多个 Prometheus 指标、OpenTelemetry 分布式追踪、结构化日志记录和请求 ID 传播。
架构#
控制面#
工作节点管理器:发现节点能力(
/get_server_info,/get_model_info),追踪负载,并在共享注册表中注册/移除节点。任务队列:序列化添加/移除请求并暴露状态(
/workers/{worker_id}),以便客户端跟踪上线进度。负载监控器:为缓存感知策略和“二选一”策略提供实时的节点负载统计信息。
健康检查器:持续探测工作节点并更新就绪状态、熔断状态和网关指标。
分词器注册表:管理动态注册的分词器,支持从 HuggingFace 或本地路径异步加载。
数据面#
HTTP 路由(常规与 PD):实现
/generate,/v1/chat/completions,/v1/completions,/v1/responses,/v1/embeddings,/v1/rerank,/v1/classify,/v1/tokenize,/v1/detokenize以及相关的管理端点。gRPC 路由:将分词后的请求直接以流式发送至 SRT gRPC 工作节点,完全运行在 Rust 中——分词器、推理解析器和工具解析器均驻留在进程内。支持单阶段和 PD 路由,包括 Embedding。
OpenAI 路由:将 OpenAI 兼容的端点代理至外部供应商(OpenAI, xAI 等),同时保持聊天历史和多轮对话编排在本地进行。
存储与隐私#
对话和响应历史记录存储在网关层(内存、none、Oracle ATP 或 PostgreSQL)。同一份历史记录可以支持多个模型或 MCP 循环,而无需将数据发送给上游供应商。
/v1/responsesAgent 工作流、MCP 会话和对话 API 共享同一存储层,从而实现对受监管工作负载的合规性。
安装#
Docker#
预构建的 Docker 镜像可在 Docker Hub 获取,支持多架构(x86_64 和 ARM64)。
docker pull lmsysorg/sgl-model-gateway:latest
前提条件#
Rust 和 Cargo
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source "$HOME/.cargo/env" rustc --version cargo --version
提供支持
pip和 virtualenv 工具的 Python 环境。
Rust 二进制文件#
cd sgl-model-gateway
cargo build --release
Python 包#
pip install maturin
# Fast development mode
cd sgl-model-gateway/bindings/python
maturin develop
# Production build
maturin build --release --out dist --features vendored-openssl
pip install --force-reinstall dist/*.whl
快速入门#
常规 HTTP 路由#
# Rust binary
./target/release/sgl-model-gateway \
--worker-urls http://worker1:8000 http://worker2:8000 \
--policy cache_aware
# Python launcher
python -m sglang_router.launch_router \
--worker-urls http://worker1:8000 http://worker2:8000 \
--policy cache_aware
gRPC 路由#
python -m sglang_router.launch_router \
--worker-urls grpc://127.0.0.1:20000 \
--model-path meta-llama/Llama-3.1-8B-Instruct \
--reasoning-parser deepseek-r1 \
--tool-call-parser json \
--host 0.0.0.0 --port 8080
部署模式#
联合启动路由与工作节点#
在一个进程中启动网关和一组 SGLang 工作节点
python -m sglang_router.launch_server \
--model meta-llama/Meta-Llama-3.1-8B-Instruct \
--dp-size 4 \
--host 0.0.0.0 \
--port 30000
带有网关参数(以 --router- 为前缀)的完整示例
python -m sglang_router.launch_server \
--host 0.0.0.0 \
--port 8080 \
--model meta-llama/Llama-3.1-8B-Instruct \
--tp-size 1 \
--dp-size 8 \
--grpc-mode \
--log-level debug \
--router-prometheus-port 10001 \
--router-tool-call-parser llama \
--router-model-path meta-llama/Llama-3.1-8B-Instruct \
--router-policy round_robin \
--router-log-level debug
独立启动 (HTTP)#
独立运行工作节点,并将网关指向它们的 HTTP 端点
# Worker nodes
python -m sglang.launch_server --model meta-llama/Meta-Llama-3.1-8B-Instruct --port 8000
python -m sglang.launch_server --model meta-llama/Meta-Llama-3.1-8B-Instruct --port 8001
# Router node
python -m sglang_router.launch_router \
--worker-urls http://worker1:8000 http://worker2:8001 \
--policy cache_aware \
--host 0.0.0.0 --port 30000
gRPC 启动#
使用 SRT gRPC 工作节点以解锁最高吞吐量并访问原生推理/工具流水线
# Workers expose gRPC endpoints
python -m sglang.launch_server \
--model meta-llama/Llama-3.1-8B-Instruct \
--grpc-mode \
--port 20000
# Router
python -m sglang_router.launch_router \
--worker-urls grpc://127.0.0.1:20000 \
--model-path meta-llama/Llama-3.1-8B-Instruct \
--reasoning-parser deepseek-r1 \
--tool-call-parser json \
--host 0.0.0.0 --port 8080
gRPC 路由支持常规 HTTP 等效服务和 PD(预填充/解码)服务。当连接模式解析为 gRPC 时,需提供 --tokenizer-path 或 --model-path(HuggingFace ID 或本地目录)。
Prefill-Decode 解耦#
拆分预填充和解码工作节点,实现 PD 感知的缓存和负载均衡
python -m sglang_router.launch_router \
--pd-disaggregation \
--prefill http://prefill1:30001 9001 \
--decode http://decode1:30011 \
--prefill-policy cache_aware \
--decode-policy power_of_two
预填充条目接受可选的引导端口(bootstrap port)。PD 模式将预填充元数据与解码输出合并,并将结果流式返回给客户端。
OpenAI 后端代理#
代理 OpenAI 兼容端点,同时保持历史记录和 MCP 会话在本地
python -m sglang_router.launch_router \
--backend openai \
--worker-urls https://api.openai.com \
--history-backend memory
OpenAI 后端模式要求每个网关实例正好有一个 --worker-urls 条目。
多模型推理网关#
启用 IGW 模式,通过单个网关路由多个模型
./target/release/sgl-model-gateway \
--enable-igw \
--policy cache_aware \
--max-concurrent-requests 512
# Register workers dynamically
curl -X POST https://:30000/workers \
-H "Content-Type: application/json" \
-d '{
"url": "http://worker-a:8000",
"model_id": "mistral",
"priority": 10,
"labels": {"tier": "gold"}
}'
API 参考#
推理端点#
方法 |
路径 |
描述 |
|---|---|---|
|
|
SGLang 生成 API |
|
|
OpenAI 兼容的聊天补全(流式/工具调用) |
|
|
OpenAI 兼容的文本补全 |
|
|
Embedding 生成(HTTP 和 gRPC) |
|
|
重排序请求 |
|
|
文本分类 |
分词端点#
网关提供支持批量处理的文本分词 HTTP 端点,旨在镜像 SGLang Python 分词 API。
方法 |
路径 |
描述 |
|---|---|---|
|
|
将文本转换为 Token ID(单个或批量) |
|
|
将 Token ID 转回文本(单个或批量) |
|
|
注册新分词器(异步,返回任务状态) |
|
|
列出所有已注册的分词器 |
|
|
通过 UUID 获取分词器信息 |
|
|
检查分词器异步加载状态 |
|
|
从注册表中移除分词器 |
分词请求#
{
"model": "meta-llama/Llama-3.1-8B-Instruct",
"prompt": "Hello, world!"
}
批量分词请求#
{
"model": "meta-llama/Llama-3.1-8B-Instruct",
"prompt": ["Hello", "World", "How are you?"]
}
分词响应#
{
"tokens": [15339, 11, 1917, 0],
"count": 4,
"char_count": 13
}
反分词请求#
{
"model": "meta-llama/Llama-3.1-8B-Instruct",
"tokens": [15339, 11, 1917, 0],
"skip_special_tokens": true
}
反分词响应#
{
"text": "Hello, world!"
}
添加分词器 (异步)#
curl -X POST https://:30000/v1/tokenizers \
-H "Content-Type: application/json" \
-d '{"name": "llama3", "source": "meta-llama/Llama-3.1-8B-Instruct"}'
响应
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"message": "Tokenizer registration queued"
}
检查状态
curl https://:30000/v1/tokenizers/550e8400-e29b-41d4-a716-446655440000/status
解析器端点#
网关提供用于解析 LLM 输出中的推理内容和函数调用的管理端点。
方法 |
路径 |
描述 |
|---|---|---|
|
|
从正常文本中分离推理内容( |
|
|
从文本中解析函数/工具调用 |
分离推理请求#
{
"text": "<think>Let me analyze this step by step...</think>The answer is 42.",
"parser": "deepseek-r1"
}
响应#
{
"normal_text": "The answer is 42.",
"reasoning_text": "Let me analyze this step by step..."
}
函数调用解析#
{
"text": "{\"name\": \"get_weather\", \"arguments\": {\"city\": \"NYC\"}}",
"parser": "json"
}
对话与响应 API#
方法 |
路径 |
描述 |
|---|---|---|
|
|
创建后台响应(Agent 循环) |
|
|
检索存储的响应 |
|
|
取消后台响应 |
|
|
删除响应 |
|
|
列出响应输入项 |
|
|
创建对话 |
|
|
获取对话 |
|
|
更新对话 |
|
|
删除对话 |
|
|
列出对话条目 |
|
|
向对话添加条目 |
|
|
获取对话条目 |
|
|
删除对话条目 |
工作节点管理 API#
方法 |
路径 |
描述 |
|---|---|---|
|
|
对工作节点注册进行排队(返回 202 Accepted) |
|
|
列出带有健康状态、负载和策略元数据的工作节点 |
|
|
检查特定工作节点或任务队列条目 |
|
|
对工作节点更新进行排队 |
|
|
对移除工作节点进行排队 |
添加工作节点#
curl -X POST https://:30000/workers \
-H "Content-Type: application/json" \
-d '{"url":"grpc://0.0.0.0:31000","worker_type":"regular"}'
列出工作节点#
curl https://:30000/workers
响应
{
"workers": [
{
"id": "2f3a0c3e-3a7b-4c3f-8c70-1b7d4c3a6e1f",
"url": "http://0.0.0.0:31378",
"model_id": "mistral",
"priority": 50,
"cost": 1.0,
"worker_type": "regular",
"is_healthy": true,
"load": 0,
"connection_mode": "Http"
}
],
"total": 1,
"stats": {
"prefill_count": 0,
"decode_count": 0,
"regular_count": 1
}
}
管理与健康检查端点#
方法 |
路径 |
描述 |
|---|---|---|
|
|
存活检查(始终返回 OK) |
|
|
就绪检查(检查健康工作节点的可用性) |
|
|
liveness 的别名 |
|
|
健康生成测试 |
|
|
来自工作节点的引擎级指标 |
|
|
列出可用模型 |
|
|
获取模型信息 |
|
|
获取服务器信息 |
|
|
清除所有缓存 |
|
|
获取所有工作节点负载 |
|
|
上传 WASM 模块 |
|
|
列出 WASM 模块 |
|
|
移除 WASM 模块 |
负载均衡策略#
策略 |
描述 |
用法 |
|---|---|---|
|
均匀随机选择 |
|
|
按顺序循环遍历工作节点 |
|
|
采样两个节点并选择负载较轻的一个 |
|
|
结合缓存局部性与负载均衡(默认) |
|
|
将工作节点分配到具有动态边界的负载桶中 |
|
缓存感知策略微调#
--cache-threshold 0.5 \
--balance-abs-threshold 32 \
--balance-rel-threshold 1.5 \
--eviction-interval-secs 120 \
--max-tree-size 67108864
参数 |
默认值 |
描述 |
|---|---|---|
|
0.3 |
缓存命中的最小前缀匹配率 |
|
64 |
重新平衡前的绝对负载差值 |
|
1.5 |
重新平衡前的相对负载比例 |
|
120 |
缓存淘汰节奏(秒) |
|
67108864 |
缓存树中的最大节点数 |
可靠性与流控#
重试#
配置指数退避重试
python -m sglang_router.launch_router \
--worker-urls http://worker1:8000 http://worker2:8001 \
--retry-max-retries 5 \
--retry-initial-backoff-ms 50 \
--retry-max-backoff-ms 30000 \
--retry-backoff-multiplier 1.5 \
--retry-jitter-factor 0.2
参数 |
默认值 |
描述 |
|---|---|---|
|
5 |
最大重试次数 |
|
50 |
初始退避时长 (ms) |
|
5000 |
最大退避时长 (ms) |
|
2.0 |
指数退避倍数 |
|
0.1 |
随机抖动因子 (0.0-1.0) |
|
false |
完全禁用重试 |
可重试的状态码 408, 429, 500, 502, 503, 504
熔断器#
针对每个工作节点的熔断器可防止级联故障
python -m sglang_router.launch_router \
--worker-urls http://worker1:8000 http://worker2:8001 \
--cb-failure-threshold 5 \
--cb-success-threshold 2 \
--cb-timeout-duration-secs 30 \
--cb-window-duration-secs 60
参数 |
默认值 |
描述 |
|---|---|---|
|
5 |
开启熔断前的连续失败次数 |
|
2 |
从半开状态转为关闭所需的成功次数 |
|
30 |
进入半开尝试前的等待时间 |
|
60 |
失败统计窗口 |
|
false |
禁用熔断器 |
熔断器状态
Closed (关闭):正常运行,允许请求
Open (开启):故障中,立即拒绝请求
Half-Open (半开):测试恢复中,允许限量请求
限流与排队#
python -m sglang_router.launch_router \
--worker-urls http://worker1:8000 http://worker2:8001 \
--max-concurrent-requests 256 \
--rate-limit-tokens-per-second 512 \
--queue-size 128 \
--queue-timeout-secs 30
超过并发限制的请求将在 FIFO 队列中等待。在以下情况返回:
队列满时返回
429 Too Many Requests队列超时过期时返回
408 Request Timeout
健康检查#
--health-check-interval-secs 30 \
--health-check-timeout-secs 10 \
--health-success-threshold 2 \
--health-failure-threshold 3 \
--health-check-endpoint /health
推理解析器集成#
网关内置了推理解析器,适用于使用显式思维块进行思维链 (CoT) 推理的模型。
支持的解析器#
解析器 ID |
模型家族 |
推理 Token |
|---|---|---|
|
DeepSeek-R1 |
|
|
Qwen-3 |
|
|
Qwen-3 Thinking |
|
|
Kimi K2 |
Unicode 推理 Token |
|
GLM-4.5/4.6/4.7 |
|
|
Step-3 |
|
|
MiniMax |
|
用法#
python -m sglang_router.launch_router \
--worker-urls grpc://127.0.0.1:20000 \
--model-path deepseek-ai/DeepSeek-R1 \
--reasoning-parser deepseek-r1
gRPC 路由会自动:
在流式输出中检测推理块
将推理内容从正常文本中分离
应用带缓冲管理的增量流式解析
处理部分 Token 检测以确保正确的流式行为
工具调用解析#
网关支持从多种格式的 LLM 输出中解析函数/工具调用。
支持的格式#
解析器 |
格式 |
描述 |
|---|---|---|
|
JSON |
标准 JSON 工具调用 |
|
Python 式 |
Python 函数调用语法 |
|
XML |
XML 格式的工具调用 |
用法#
python -m sglang_router.launch_router \
--worker-urls grpc://127.0.0.1:20000 \
--model-path meta-llama/Llama-3.1-8B-Instruct \
--tool-call-parser json
分词器管理#
分词器来源#
网关支持多种分词器后端:
HuggingFace:通过模型 ID 从 HuggingFace Hub 加载
本地:从本地
tokenizer.json或目录加载Tiktoken:自动检测 OpenAI GPT 模型 (gpt-4, davinci 等)
配置#
# HuggingFace model
--model-path meta-llama/Llama-3.1-8B-Instruct
# Local tokenizer
--tokenizer-path /path/to/tokenizer.json
# With chat template override
--chat-template /path/to/template.jinja
分词器缓存#
二级缓存实现最佳性能:
缓存 |
类型 |
描述 |
|---|---|---|
L0 |
精确匹配 |
针对重复提示词的全字符串缓存 |
L1 |
前缀匹配 |
针对增量提示词的前缀边界匹配 |
--enable-l0-cache \
--l0-max-entries 10000 \
--enable-l1-cache \
--l1-max-memory 52428800 # 50MB
MCP 集成#
网关提供原生的模型上下文协议 (MCP) 客户端集成,用于工具执行。
支持的传输协议#
传输协议 |
描述 |
|---|---|
STDIO |
本地进程执行 |
SSE |
服务器发送事件 (HTTP) |
Streamable |
双向流 |
配置#
python -m sglang_router.launch_router \
--mcp-config-path /path/to/mcp-config.yaml \
--worker-urls http://worker1:8000
MCP 配置文件#
servers:
- name: "filesystem"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
protocol: "stdio"
required: false
- name: "github"
url: "https://api.github.com/mcp"
token: "ghp_xxxxx"
protocol: "sse"
required: false
- name: "custom-tools"
url: "https://tools.example.com/mcp"
protocol: "streamable"
required: true
pool:
max_connections: 100
idle_timeout: 300
proxy:
http: "http://proxy.internal:8080"
https: "https://proxy.internal:8443"
no_proxy: "localhost,127.0.0.1,*.internal"
inventory:
enable_refresh: true
tool_ttl: 300
refresh_interval: 300
服务发现 (Kubernetes)#
通过 Kubernetes Pod 选择器启用自动工作节点发现
python -m sglang_router.launch_router \
--service-discovery \
--selector app=sglang-worker role=inference \
--service-discovery-namespace production \
--service-discovery-port 8000
PD 模式发现#
--pd-disaggregation \
--prefill-selector app=sglang component=prefill \
--decode-selector app=sglang component=decode \
--service-discovery
预填充 Pod 可以通过 sglang.ai/bootstrap-port 注解暴露引导端口。RBAC 必须允许对 Pod 进行 get, list, 和 watch 操作。
历史记录与数据连接器#
后端 |
描述 |
用法 |
|---|---|---|
|
内存存储(默认) |
|
|
不持久化 |
|
|
Oracle 自主数据库 |
|
|
PostgreSQL 数据库 |
|
Oracle 配置#
# Connection descriptor
export ATP_DSN="(description=(address=(protocol=tcps)(port=1522)(host=adb.region.oraclecloud.com))(connect_data=(service_name=service_name)))"
# Or TNS alias (requires wallet)
export ATP_TNS_ALIAS="sglroutertestatp_high"
export ATP_WALLET_PATH="/path/to/wallet"
# Credentials
export ATP_USER="admin"
export ATP_PASSWORD="secret"
export ATP_POOL_MIN=4
export ATP_POOL_MAX=32
python -m sglang_router.launch_router \
--backend openai \
--worker-urls https://api.openai.com \
--history-backend oracle
PostgreSQL 配置#
export POSTGRES_DB_URL="postgres://user:password@host:5432/dbname"
python -m sglang_router.launch_router \
--backend openai \
--worker-urls https://api.openai.com \
--history-backend postgres
WASM 中间件#
网关支持 WebAssembly (WASM) 中间件模块,用于自定义请求/响应处理。这使得组织能够在不修改或重新编译网关的情况下,实现特定逻辑,如身份验证、限流、计费、日志记录等。
概述#
WASM 中间件运行在具有内存隔离、无网络/文件系统访问权限且资源限制可调的沙盒环境中。
挂载点 |
执行时机 |
用例 |
|---|---|---|
|
转发至工作节点前 |
鉴权、限流、请求修改 |
|
接收到节点响应后 |
日志、响应修改、错误处理 |
操作 |
描述 |
|---|---|
|
不经修改继续执行 |
|
使用 HTTP 状态码拒绝请求 |
|
修改请求头、正文或状态 |
示例#
完整的运行示例位于 examples/wasm/
示例 |
描述 |
|---|---|
|
受保护路由的 API 密钥验证 |
|
针对每个客户端的限流(请求数/每分钟) |
|
请求追踪头与响应修改 |
接口定义位于 src/wasm/interface。
构建模块#
# Prerequisites
rustup target add wasm32-wasip2
cargo install wasm-tools
# Build
cargo build --target wasm32-wasip2 --release
# Convert to component format
wasm-tools component new \
target/wasm32-wasip2/release/my_middleware.wasm \
-o my_middleware.component.wasm
部署模块#
# Enable WASM support
python -m sglang_router.launch_router \
--worker-urls http://worker1:8000 \
--enable-wasm
# Upload module
curl -X POST https://:30000/wasm \
-H "Content-Type: application/json" \
-d '{
"modules": [{
"name": "auth-middleware",
"file_path": "/absolute/path/to/auth.component.wasm",
"module_type": "Middleware",
"attach_points": [{"Middleware": "OnRequest"}]
}]
}'
# List modules
curl https://:30000/wasm
# Remove module
curl -X DELETE https://:30000/wasm/{module_uuid}
运行配置#
参数 |
默认值 |
描述 |
|---|---|---|
|
1024 (64MB) |
WASM 最大内存 |
|
1000 |
执行超时 |
|
1MB |
栈大小限制 |
|
10 |
每个工作线程缓存的模块数 |
注意:限流状态是基于每个工作线程的,不跨网关副本共享。对于生产环境,建议在共享层(如 Redis)实现限流。
语言绑定#
SGLang 模型网关提供官方的 Python 和 Go 语言绑定,以便集成到不同的技术栈和组织需求中。
Python 绑定#
Python 绑定提供了一个基于 PyO3 的 Rust 网关库封装。这是一个直接从 Python 调用网关服务器启动的绑定。
安装#
# From PyPI
pip install sglang-router
# Development build
cd sgl-model-gateway/bindings/python
pip install maturin && maturin develop --features vendored-openssl
用法#
本文件贯穿使用了 Python 绑定。详细示例请参阅 快速入门 和 部署模式 章节。
关键组件
拥有 50 多个配置选项的
RouterArgs数据类用于程序化启动的
Router.from_args()CLI 命令:
smg launch,smg server,python -m sglang_router.launch_router
Go 绑定#
Go 绑定为使用 Go 基础设施的组织提供了高性能的 gRPC 客户端库。它非常适合:
与内部 Go 服务和工具集成
高性能客户端应用程序
构建自定义的 OpenAI 兼容代理服务器
架构#
┌─────────────────────────────────────────┐
│ High-Level Go API │
│ (client.go - OpenAI-style interface) │
├─────────────────────────────────────────┤
│ gRPC Layer │
├─────────────────────────────────────────┤
│ Rust FFI Layer │
│ (Tokenization, Parsing, Conversion) │
└─────────────────────────────────────────┘
关键特性
通过 FFI 实现原生 Rust 分词(线程安全、无锁)
支持带上下文取消的完整流式传输
可配置的通道缓冲区大小以支持高并发
内置工具调用解析和聊天模板应用
安装#
# Build the FFI library first
cd sgl-model-gateway/bindings/golang
make build && make lib
# Then use in your Go project
go get github.com/sgl-project/sgl-go-sdk
要求:Go 1.24+, Rust 工具链
示例#
完整的运行示例位于 bindings/golang/examples/
示例 |
描述 |
|---|---|
|
非流式聊天补全 |
|
基于 SSE 的流式聊天补全 |
|
完整的 OpenAI 兼容 HTTP 服务器 |
# Run examples
cd sgl-model-gateway/bindings/golang/examples/simple && ./run.sh
cd sgl-model-gateway/bindings/golang/examples/streaming && ./run.sh
cd sgl-model-gateway/bindings/golang/examples/oai_server && ./run.sh
测试#
cd sgl-model-gateway/bindings/golang
# Unit tests
go test -v ./...
# Integration tests (requires running SGLang server)
export SGL_GRPC_ENDPOINT=grpc://:20000
export SGL_TOKENIZER_PATH=/path/to/tokenizer
go test -tags=integration -v ./...
对比#
特性 |
Python |
Go |
|---|---|---|
主要用途 |
网关服务器启动器 |
gRPC 客户端库 |
CLI 支持 |
完整 CLI (smg, sglang-router) |
仅库文件 |
K8s 发现 |
原生支持 |
不适用(客户端库) |
PD 模式 |
内置 |
不适用(客户端库) |
何时使用 Python:启动和管理网关服务器、服务发现、PD 解耦。
何时使用 Go:构建自定义客户端应用程序、集成 Go 微服务、OpenAI 兼容代理服务器。
安全性与身份验证#
路由 API 密钥#
python -m sglang_router.launch_router \
--api-key "your-router-api-key" \
--worker-urls http://worker1:8000
客户端必须为受保护的端点提供 Authorization: Bearer <key>。
工作节点 API 密钥#
# Add worker with explicit key
curl -H "Authorization: Bearer router-key" \
-X POST https://:8080/workers \
-H "Content-Type: application/json" \
-d '{"url":"http://worker:8000","api_key":"worker-key"}'
安全配置#
无身份验证(默认):仅在信任环境中使用
仅路由身份验证:客户端向网关验证身份
仅工作节点身份验证:网关开放,工作节点需要密钥
全身份验证:网关和工作节点均受保护
网关服务器 TLS (HTTPS)#
启用 TLS 以通过 HTTPS 提供网关服务
python -m sglang_router.launch_router \
--worker-urls http://worker1:8000 \
--tls-cert-path /path/to/server.crt \
--tls-key-path /path/to/server.key
参数 |
描述 |
|---|---|
|
服务器证书路径 (PEM 格式) |
|
服务器私钥路径 (PEM 格式) |
两个参数必须同时提供。网关使用 rustls 配合 ring 加密提供者进行 TLS 终结。如果未配置 TLS,网关将回退到普通 HTTP。
用于工作节点通信的 mTLS#
在 HTTP 模式下,启用双向 TLS (mTLS) 以实现与工作节点的安全通信
python -m sglang_router.launch_router \
--worker-urls https://worker1:8443 https://worker2:8443 \
--client-cert-path /path/to/client.crt \
--client-key-path /path/to/client.key \
--ca-cert-path /path/to/ca.crt
参数 |
描述 |
|---|---|
|
用于 mTLS 的客户端证书路径 (PEM 格式) |
|
用于 mTLS 的客户端私钥路径 (PEM 格式) |
|
用于验证工作节点 TLS 的 CA 证书路径 (PEM 格式,可重复) |
关键点
客户端证书和私钥必须同时提供
可以通过多个
--ca-cert-path标志添加多个 CA 证书配置 TLS 时使用 rustls 后端
为所有工作节点创建一个单一 HTTP 客户端(假设为单一安全域)
为长连接启用了 TCP keepalive (30 秒)
完整 TLS 配置示例#
网关 HTTPS + 工作节点 mTLS + API 密钥身份验证
python -m sglang_router.launch_router \
--worker-urls https://worker1:8443 https://worker2:8443 \
--tls-cert-path /etc/certs/server.crt \
--tls-key-path /etc/certs/server.key \
--client-cert-path /etc/certs/client.crt \
--client-key-path /etc/certs/client.key \
--ca-cert-path /etc/certs/ca.crt \
--api-key "secure-api-key" \
--policy cache_aware
可观测性#
Prometheus 指标#
使用 --prometheus-host/--prometheus-port 启用(默认为 0.0.0.0:29000)。
指标类别 (40+ 项指标)#
层级 |
前缀 |
指标 |
|---|---|---|
HTTP |
|
|
路由 |
|
|
推理 |
|
|
工作节点 |
|
|
熔断器 |
|
|
重试 |
|
|
服务发现 (Discovery) |
|
|
MCP |
|
|
数据库 (Database) |
|
|
关键推理指标 (gRPC 模式)#
指标 (Metric) |
类型 |
描述 |
|---|---|---|
|
直方图 (Histogram) |
首标输出时间 (TTFT) |
|
直方图 (Histogram) |
逐标输出时间 (TPOT) |
|
计数器 (Counter) |
总 Token 数 (输入/输出) |
|
直方图 (Histogram) |
端到端生成时间 |
持续时间分桶 (Duration Buckets)#
1ms, 5ms, 10ms, 25ms, 50ms, 100ms, 250ms, 500ms, 1s, 2.5s, 5s, 10s, 15s, 30s, 45s, 60s, 90s, 120s, 180s, 240s
OpenTelemetry 链路追踪#
通过 OTLP 导出启用分布式追踪
python -m sglang_router.launch_router \
--worker-urls http://worker1:8000 \
--enable-trace \
--otlp-traces-endpoint localhost:4317
特性#
OTLP/gRPC 导出器(默认端口 4317)
支持 HTTP 和 gRPC 的 W3C Trace Context 传播
批量 Span 处理(500ms 延迟,64 span 批处理大小)
自定义过滤以减少噪点
向游 Worker 请求注入追踪上下文
服务名称:
sgl-router
日志#
python -m sglang_router.launch_router \
--worker-urls http://worker1:8000 \
--log-level debug \
--log-dir ./router_logs
具有可选文件接收器的结构化追踪。日志级别:debug, info, warn, error。
Request ID 传播#
--request-id-headers x-request-id x-trace-id x-correlation-id
响应包含用于关联的 x-request-id 头部。
生产环境建议#
本节为在生产环境中部署 SGLang Model Gateway 提供指导。
安全最佳实践#
在生产环境中务必启用 TLS
python -m sglang_router.launch_router \
--worker-urls https://worker1:8443 https://worker2:8443 \
--tls-cert-path /etc/certs/server.crt \
--tls-key-path /etc/certs/server.key \
--client-cert-path /etc/certs/client.crt \
--client-key-path /etc/certs/client.key \
--ca-cert-path /etc/certs/ca.crt \
--api-key "${ROUTER_API_KEY}"
安全检查清单
为网关 HTTPS 终点启用 TLS
当 Worker 处于非信任网络时,启用 mTLS 进行 Worker 通信
设置
--api-key以保护路由端点使用 Kubernetes Secrets 或机密管理器管理凭据
定期轮换证书和 API 密钥
通过防火墙或网络策略限制网络访问
高可用性 (High Availability)#
扩缩容策略
网关支持在负载均衡器后运行多个副本以实现高可用性。但是,有一些重要的注意事项:
组件 |
是否副本间共享 |
影响 |
|---|---|---|
Worker 注册表 |
否 (独立) |
每个副本独立发现 Worker |
Radix 缓存树 |
否 (独立) |
缓存命中率可能下降 10-20% |
断路器状态 |
否 (独立) |
每个副本独立跟踪故障 |
速率限制 (Rate Limiting) |
否 (独立) |
限制应用于每个副本,而非全局 |
建议
优先选择水平扩展而非垂直扩展:部署多个较小的网关副本,而不是一个具有过度 CPU 和内存的大型实例。这提供了:
更好的容错性(单个副本故障不会导致网关瘫痪)
更可预测的资源使用
更简单的容量规划
使用 Kubernetes 服务发现:让网关自动发现并管理 Worker
python -m sglang_router.launch_router \ --service-discovery \ --selector app=sglang-worker \ --service-discovery-namespace production
接受缓存效率的权衡:在多副本情况下,缓存感知路由策略的 Radix 树在副本间不同步。这意味着:
每个副本构建自己的缓存树
来自同一用户的请求可能会命中不同的副本
预期缓存命中率降低:10-20%
考虑到 HA 带来的收益,这通常是可接受的
配置会话亲和性(可选):如果缓存效率至关重要,请为负载均衡器配置会话亲和性(基于请求的一致性哈希,例如用户 ID 或 API 密钥)。
高可用架构示例
┌─────────────────┐
│ Load Balancer │
│ (L4/L7) │
└────────┬────────┘
┌──────────────┼──────────────┐
│ │ │
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ Gateway │ │ Gateway │ │ Gateway │
│ Replica 1 │ │ Replica 2 │ │ Replica 3 │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ │ │
└──────────────┼──────────────┘
│
┌──────────────┼──────────────┐
│ │ │
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ Worker │ │ Worker │ │ Worker │
│ Pod 1 │ │ Pod 2 │ │ Pod N │
└───────────┘ └───────────┘ └───────────┘
性能#
使用 gRPC 模式以获得高吞吐量
gRPC 模式为 SGLang Worker 提供了最高性能
# Start workers in gRPC mode
python -m sglang.launch_server \
--model meta-llama/Llama-3.1-8B-Instruct \
--grpc-mode \
--port 20000
# Configure gateway for gRPC
python -m sglang_router.launch_router \
--worker-urls grpc://worker1:20000 grpc://worker2:20000 \
--model-path meta-llama/Llama-3.1-8B-Instruct \
--policy cache_aware
gRPC 的性能优势
原生 Rust 分词(无 Python 开销)
更低延迟的流式输出
内置推理推理器(reasoning parser)执行
网关中的工具调用解析
减少序列化开销
调优建议
参数 |
建议 |
原因 |
|---|---|---|
|
|
最适合重复提示词,延迟降低约 30% |
|
Worker 数量的 2-4 倍 |
在最大化吞吐量的同时防止过载 |
|
最大并发数的 2 倍 |
缓冲突发流量 |
|
基于最大生成长度设置 |
防止请求卡死 |
Kubernetes 部署#
用于服务发现的 Pod 标签
为了让网关自动发现 Worker,请为您的 Worker Pod 打上一致的标签
# Worker Deployment (Regular Mode)
apiVersion: apps/v1
kind: Deployment
metadata:
name: sglang-worker
namespace: production
spec:
replicas: 4
selector:
matchLabels:
app: sglang-worker
component: inference
template:
metadata:
labels:
app: sglang-worker
component: inference
model: llama-3-8b
spec:
containers:
- name: worker
image: lmsysorg/sglang:latest
ports:
- containerPort: 8000
name: http
- containerPort: 20000
name: grpc
用于发现的网关配置
python -m sglang_router.launch_router \
--service-discovery \
--selector app=sglang-worker component=inference \
--service-discovery-namespace production \
--service-discovery-port 8000
PD (Prefill/Decode) 模式标签
# Prefill Worker
metadata:
labels:
app: sglang-worker
component: prefill
annotations:
sglang.ai/bootstrap-port: "9001"
# Decode Worker
metadata:
labels:
app: sglang-worker
component: decode
用于 PD 发现的网关配置
python -m sglang_router.launch_router \
--service-discovery \
--pd-disaggregation \
--prefill-selector app=sglang-worker component=prefill \
--decode-selector app=sglang-worker component=decode \
--service-discovery-namespace production
RBAC 权限要求
网关需要监听 (watch) Pod 的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: sglang-gateway
namespace: production
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: sglang-gateway
namespace: production
subjects:
- kind: ServiceAccount
name: sglang-gateway
namespace: production
roleRef:
kind: Role
name: sglang-gateway
apiGroup: rbac.authorization.k8s.io
使用 PromQL 进行监控#
配置 Prometheus 抓取网关指标端点(默认::29000/metrics)。
核心仪表板
1. 请求速率与延迟
# Request rate by endpoint
sum(rate(smg_http_requests_total[5m])) by (path, method)
# P50 latency
histogram_quantile(0.50, sum(rate(smg_http_request_duration_seconds_bucket[5m])) by (le))
# P99 latency
histogram_quantile(0.99, sum(rate(smg_http_request_duration_seconds_bucket[5m])) by (le))
# Error rate
sum(rate(smg_http_responses_total{status=~"5.."}[5m])) / sum(rate(smg_http_responses_total[5m]))
2. Worker 健康状态
# Healthy workers
sum(smg_worker_pool_size)
# Active connections per worker
smg_worker_connections_active
# Worker health check failures
sum(rate(smg_worker_health_checks_total{result="failure"}[5m])) by (worker_id)
3. 断路器状态
# Circuit breaker states (0=closed, 1=open, 2=half-open)
smg_worker_cb_state
# Circuit breaker transitions
sum(rate(smg_worker_cb_transitions_total[5m])) by (worker_id, from_state, to_state)
# Workers with open circuits
count(smg_worker_cb_state == 1)
4. 推理性能 (gRPC 模式)
# Time to first token (P50)
histogram_quantile(0.50, sum(rate(smg_router_ttft_seconds_bucket[5m])) by (le, model))
# Time per output token (P99)
histogram_quantile(0.99, sum(rate(smg_router_tpot_seconds_bucket[5m])) by (le, model))
# Token throughput
sum(rate(smg_router_tokens_total[5m])) by (model, direction)
# Generation duration P95
histogram_quantile(0.95, sum(rate(smg_router_generation_duration_seconds_bucket[5m])) by (le))
5. 速率限制与队列情况
# Rate limit rejections
sum(rate(smg_http_rate_limit_total{decision="rejected"}[5m]))
# Queue depth (if using concurrency limiting)
smg_worker_requests_active
# Retry attempts
sum(rate(smg_worker_retries_total[5m])) by (worker_id)
# Exhausted retries (failures after all retries)
sum(rate(smg_worker_retries_exhausted_total[5m]))
6. MCP 工具执行情况
# Tool call rate
sum(rate(smg_mcp_tool_calls_total[5m])) by (server, tool)
# Tool latency P95
histogram_quantile(0.95, sum(rate(smg_mcp_tool_duration_seconds_bucket[5m])) by (le, tool))
# Active MCP server connections
smg_mcp_servers_active
警报规则示例
groups:
- name: sglang-gateway
rules:
- alert: HighErrorRate
expr: |
sum(rate(smg_http_responses_total{status=~"5.."}[5m]))
/ sum(rate(smg_http_responses_total[5m])) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate on SGLang Gateway"
- alert: CircuitBreakerOpen
expr: count(smg_worker_cb_state == 1) > 0
for: 2m
labels:
severity: warning
annotations:
summary: "Worker circuit breaker is open"
- alert: HighLatency
expr: |
histogram_quantile(0.99, sum(rate(smg_http_request_duration_seconds_bucket[5m])) by (le)) > 30
for: 5m
labels:
severity: warning
annotations:
summary: "P99 latency exceeds 30 seconds"
- alert: NoHealthyWorkers
expr: sum(smg_worker_pool_size) == 0
for: 1m
labels:
severity: critical
annotations:
summary: "No healthy workers available"
配置参考#
核心设置#
参数 |
类型 |
默认值 |
描述 |
|---|---|---|---|
|
str |
127.0.0.1 |
路由主机 |
|
int |
30000 |
路由端口 |
|
list |
[] |
Worker URL 列表 (HTTP 或 gRPC) |
|
str |
cache_aware |
路由策略 |
|
int |
-1 |
并发限制 (-1 表示禁用) |
|
int |
600 |
请求超时时间 |
|
int |
256MB |
最大请求载荷大小 |
预填充/解码 (Prefill/Decode)#
参数 |
类型 |
默认值 |
描述 |
|---|---|---|---|
|
flag |
false |
启用 PD 分离模式 |
|
list |
[] |
Prefill URL 列表 + 可选的引导端口 |
|
list |
[] |
Decode URL 列表 |
|
str |
无 |
覆盖 Prefill 节点的策略 |
|
str |
无 |
覆盖 Decode 节点的策略 |
|
int |
600 |
Worker 初始化超时 |
Kubernetes 服务发现#
参数 |
类型 |
描述 |
|---|---|---|
|
flag |
启用服务发现 |
|
list |
标签选择器 (key=value) |
|
list |
PD 模式选择器 |
|
str |
要监听的命名空间 |
|
int |
Worker 端口(默认 80) |
|
str |
引导端口的注解 |
TLS 配置#
参数 |
类型 |
描述 |
|---|---|---|
|
str |
用于网关 HTTPS 的服务端证书 (PEM) |
|
str |
用于网关 HTTPS 的服务端私钥 (PEM) |
|
str |
用于 Worker mTLS 的客户端证书 (PEM) |
|
str |
用于 Worker mTLS 的客户端私钥 (PEM) |
|
str |
用于验证 Worker 的 CA 证书 (PEM,可重复) |
故障排查#
Worker 永不就绪#
增加 --worker-startup-timeout-secs 或确保在路由启动前健康检查已有响应。
负载不均 / 某些 Worker 过热#
按 Worker 检查 smg_router_requests_total 指标,并调整缓存感知阈值(--balance-*, --cache-threshold)。
断路器频繁切换 (Flapping)#
增加 --cb-failure-threshold 或延长超时/窗口期。考虑暂时禁用重试。
队列溢出 (429)#
增加 --queue-size 或减少客户端并发量。确保 --max-concurrent-requests 与下游容量匹配。
内存持续增长#
减小 --max-tree-size 或降低 --eviction-interval-secs 以进行更激进的缓存清理。
调试#
python -m sglang_router.launch_router \
--worker-urls http://worker1:8000 \
--log-level debug \
--log-dir ./router_logs
gRPC 连接问题#
确保 Worker 以 --grpc-mode 启动,并验证已向路由提供了 --model-path 或 --tokenizer-path。
分词器 (Tokenizer) 加载失败#
检查私有模型的 HuggingFace Hub 凭据(HF_TOKEN 环境变量)。验证本地路径是否可访问。
SGLang Model Gateway 随 SGLang 运行时不断演进。在采用新功能或贡献改进时,请保持 CLI 标志、集成和文档的一致性。