私有化部署场景下的 LLM 请求调度网关,支持多模型多节点的请求路由、优先级队列和负载均衡。
在私有化环境中,存在多台不同配置的 GPU 服务器,每台服务器部署的模型可能不同(如节点 A 部署 Qwen3-235B,节点 B 部署 Qwen3-32B),并发上限也不同。
调用方不应关心请求被分发到哪台机器,只需指定模型名并提交请求。
| 功能 | 说明 |
|---|---|
| 节点注册与健康检查 | GPU 节点启动时注册自身信息,scheduler 定期心跳检测 |
| 模型路由 + 负载均衡 | 根据请求的 model 字段匹配可用节点,按当前负载选择最优节点 |
| 请求排队与优先级 | 所有匹配节点满载时,请求进入优先级队列等待 |
| 透明转发 | 作为反向代理,将请求透传到目标节点的 OpenAI 兼容 API |
| 并发控制 | 按节点维度严格控制并发数,防止 GPU OOM |
| 请求持久化 | SQLite 存储请求记录和指标,支持历史查询和统计分析 |
| 管理面板 | 内置 Web UI,可视化监控节点状态、请求记录和统计数据 |
# 编译(含前端)
make build
# 仅编译后端(跳过前端构建)
make build-only
# 直接运行
make run
# 或运行编译后的二进制
./build/llm-scheduler
# 构建镜像
make docker
# 运行容器
docker run -d \
-p 8080:8080 \
-v $(pwd)/config.yaml:/app/config.yaml \
-v $(pwd)/data:/app/data \
llm-scheduler:latest
配置文件 config.yaml:
server:
port: 8080 # 服务端口
read_timeout: 30s # 读取超时
write_timeout: 60s # 写入超时
database:
path: "./data/scheduler.db" # SQLite 数据库路径
cleanup_enabled: true # 是否启用自动清理
retention_days: 7 # 数据保留天数
cleanup_interval: 1h # 清理间隔
scheduler:
max_queue_size: 10000 # 优先级队列容量
worker_count: 10 # 调度工作线程数
health_check_interval: 30s # 健康检查周期
health_check_timeout: 5s # 健康检查超时
request_timeout: 300s # 请求超时时间
logging:
level: info # 日志级别: debug, info, warn, error
format: json # 日志格式: json, console
auth:
api_keys: [] # /v1/* API 密钥列表,为空则不验证
admin_api_keys: [] # /admin/* API 密钥列表,为空则不验证
支持环境变量覆盖,格式为 LLM_SCHEDULER_<SECTION>_<KEY>,例如:
LLM_SCHEDULER_SERVER_PORT=9090LLM_SCHEDULER_DATABASE_PATH=/data/scheduler.db透传 LLM 请求到目标节点(OpenAI 兼容格式)。
请求头:
| Header | 说明 |
|---|---|
Authorization | Bearer token 认证(可选) |
X-Priority | 优先级:low / normal(默认) / high / critical |
请求体:
{
"model": "qwen3-235b",
"messages": [
{"role": "user", "content": "Hello"}
],
"stream": true
}
响应: 透传目标节点的响应(支持流式 SSE)
注册 GPU 节点。
{
"id": "node-1",
"address": "http://192.168.1.10:8000",
"models": ["qwen3-235b", "qwen3-32b"],
"max_concurrent": 4,
"weight": 100
}
获取所有节点列表。
获取单个节点详情。
注销节点。
获取请求统计信息。
响应:
{
"total_requests": 1000,
"pending_requests": 5,
"processing_count": 10,
"completed_count": 980,
"failed_count": 5,
"avg_latency_ms": 1234.5
}
获取按模型分组的统计信息。
响应:
{
"models": [
{
"model": "qwen3-235b",
"request_count": 500,
"avg_latency_ms": 2000.0
}
]
}
列出请求记录。
查询参数:
| 参数 | 说明 |
|---|---|
status | 按状态过滤:pending, processing, completed, failed |
model | 按模型过滤 |
node_id | 按节点过滤 |
limit | 返回数量限制(默认 100) |
offset | 分页偏移 |
start_time | 开始时间(RFC3339 格式) |
end_time | 结束时间(RFC3339 格式) |
获取单个请求详情。
获取调度器状态(队列大小、节点数量等)。
健康检查端点(无需认证)。
docwise-agent llm-scheduler GPU 节点 | | | |-- POST /v1/chat/completions ------>| | | (model=qwen3-235b, X-Priority) | | | |-- 按 model 筛选节点 --------------->| | |-- 选择负载最低节点 (least-conn) --->| | | (无可用节点则入队等待) | | | | | |-- 透传原始请求体 ----------------->| | | POST {node}/v1/chat/completions | | | | |<-- 流式/非流式响应透传 ------------|<-- 响应 ----------------------------|- | | (释放槽位) |
通过 X-Priority 请求头指定优先级,影响队列内的排序,不会抢占已在处理中的请求:
| 优先级 | 说明 |
|---|---|
low | 后台任务,排在队尾 |
normal | 默认优先级 |
high | 优先于 normal/low 被消费 |
critical | 排在队首,优先于所有等待中的请求(仍需等待空闲槽位) |
llm-scheduler/ ├── cmd/server/main.go # 程序入口 ├── internal/ │ ├── config/config.go # 配置加载 │ ├── handler/ │ │ ├── proxy.go # 代理接口处理 │ │ ├── node.go # 节点管理接口 │ │ └── admin.go # 管理接口 │ ├── middleware/ │ │ ├── auth.go # 认证中间件 │ │ ├── priority.go # 优先级提取 │ │ └── logging.go # 请求日志 │ ├── model/ │ │ ├── node.go # GPU 节点模型 │ │ ├── request.go # 调度请求模型 │ │ └── priority.go # 优先级定义 │ ├── scheduler/ │ │ ├── queue.go # 优先级队列 │ │ ├── dispatcher.go # 调度分发器 │ │ ├── balancer.go # 负载均衡器 │ │ └── pool.go # 节点池管理 │ ├── proxy/ │ │ ├── forwarder.go # HTTP 转发器 │ │ └── stream.go # SSE 流式处理 │ ├── store/sqlite.go # SQLite 请求存储 │ ├── worker/healthcheck.go # 健康检查 │ └── router/router.go # 路由配置 ├── web/ # 前端源码 (Vue 3 + Naive UI) │ ├── src/ │ │ ├── views/ # 页面组件 │ │ ├── api/ # API 调用 │ │ └── components/ # 通用组件 │ ├── package.json │ └── vite.config.js ├── config.yaml # 配置文件 ├── Dockerfile # Docker 构建 ├── Makefile # 构建脚本 └── go.mod # Go 模块
# 完整构建(前端 + 后端)
make build
# 仅构建后端
make build-only
# 运行后端
make run
# 前端开发
make web-install # 安装前端依赖
make web-dev # 启动前端开发服务器 (localhost:5173)
make web-build # 构建前端
# 其他
make test # 测试
make lint # 代码检查
make tidy # 整理依赖
make clean # 清理构建产物
make docker # 构建 Docker 镜像
启动服务后访问 http://localhost:8080 即可打开管理面板。
功能页面:
| 页面 | 功能 |
|---|---|
| 仪表盘 | 实时监控队列、节点状态、请求统计(5 秒自动刷新) |
| 节点管理 | 查看/注册/删除 GPU 节点 |
| 请求记录 | 请求历史列表,支持状态筛选、分页、详情查看 |
| 统计分析 | 按模型分组的请求统计和延迟分析 |
前端开发:
# 终端 1:启动后端
make run
# 终端 2:启动前端开发服务器(支持热更新)
make web-dev
前端开发服务器会自动代理 /admin 和 /health 请求到后端(localhost:8080)。
MIT