mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-09-19 16:39:15 +00:00
chore: bump version to 1.4.0, document cooldown probing and elastic pools
README: new "冷却与半冷却探测(自愈调度)" section with the per-class cooldown table (5xx exponential to 5min / 401-403 10min / 429 30s fixed / quota aligned to its window), the probe-slot formula and the ordering rule that probes are tried last. The LuaJIT section now says the pool is an elastic ceiling rather than a preallocation and documents both step formulas. Headline figures replaced with measured ones: idle ~10 MB, ~19 MB starting with a 29 MB audit log, and a new bullet for on-demand log loading. package.json also loses a `\u2014` escape and the broken indentation that an earlier edit left in the electron-builder block.
This commit is contained in:
41
README.md
41
README.md
@ -16,7 +16,8 @@
|
||||
### 极致轻量
|
||||
|
||||
- **单二进制**:编译后约 10MB,零运行时依赖(仅依赖系统 libc),部署即用
|
||||
- **极低内存占用**:空闲状态仅 ~15MB RSS,满载并发 100+ 请求时峰值 < 100MB
|
||||
- **极低内存占用**:空闲 ~10MB RSS,带 29MB 历史审计日志启动仅 ~19MB,满载并发 100+ 请求时峰值 < 100MB
|
||||
- **日志按需加载**:审计日志不常驻内存——默认只加载首屏,下滚自动分页,CSV 导出流式写出(O(1) 内存),离页即释放
|
||||
- **零运行时依赖**:纯 Go + LuaJIT 静态链接,无需安装 Python/Node/Java 等运行时
|
||||
- **启动极快**:冷启动 < 200ms,热重载配置 < 10ms
|
||||
|
||||
@ -24,6 +25,7 @@
|
||||
|
||||
- **多密钥多租户**:支持无限密钥,每个密钥独立角色、模型范围、Token 配额、重置周期
|
||||
- **AUTO 智能调度**:基于优先级档位的分级调度,同优先级源自动轮询负载均衡,故障自动毫秒级故障转移
|
||||
- **自愈冷却**:冷却上限 5 分钟,过半后放行 1 个探测请求,上游/额度恢复即刻回归轮询,无需等满冷却窗口
|
||||
- **Token 配额管理**:精确到模型级别的 Token 配额控制,支持小时/周/月/自定义小时周期自动重置
|
||||
- **同优先级源负载均衡**:同一优先级档位的多个源,请求自动 Round-Robin 均匀分发,故障毫秒级故障转移
|
||||
- **Source-Model 前缀路由**:支持 `source-model`/`source:model`/`source/model` 精确指定上游源
|
||||
@ -37,7 +39,7 @@
|
||||
|
||||
### 灵活的协议适配
|
||||
|
||||
- **LuaJIT VM**:每个适配器独立 VM + worker 池,安全并发,Lua 脚本热加载无需重启
|
||||
- **LuaJIT VM**:每个适配器独立 VM + **弹性 worker 池**(按需扩缩容,空闲时自动回收),安全并发,Lua 脚本热加载无需重启
|
||||
- **Lua 适配器协议**:`transform_request` / `transform_response` / `transform_stream_chunk` 双向转换
|
||||
- **动态请求头钩子**:`build_headers(meta)` 支持 HMAC 签名、动态 Header 注入
|
||||
- **多模态透传**:`image_url` 等多模态内容在多源间无损透传,Anthropic/Gemini/Ollama 自动转换
|
||||
@ -60,6 +62,12 @@ Groq、Mistral、Ollama、KimiCode…)通过 **Lua 适配器** 做协议转换
|
||||
- **生图**:`POST /v1/images/generations`,`kind: image` 的模型独立路由。
|
||||
- **多模态**:`content` 数组(`image_url` 等)在多源间无损透传,Anthropic/Gemini/Ollama 自动转换。
|
||||
- **LuaJIT VM**:基于 golua 绑定的 LuaJIT,每个适配器独立 VM + worker 池,安全并发。
|
||||
池是 **弹性** 的:`Σ max_concurrent` 只是上限而非预分配,状态按需创建、空闲时自动回收,
|
||||
因此空载网关几乎不持有 Lua 状态(启动 0 个)。
|
||||
- 扩容步长由适配器最大并发决定:`clamp(ceil(max/8), 1, 8)`,且仅在**真实并发争用**
|
||||
(所有现有状态均已占用)时批量预热,顺序流量始终只用 1 个状态。
|
||||
- 缩容步长由当前连接数决定:`clamp(ceil(冗余/(1+占用)), 1, 冗余)`——无连接时一轮收到
|
||||
常驻下限,忙时每轮只释放 1 个,保护热路径。WebUI「适配器」页展示实时池指标。
|
||||
- **disable_thinking**:请求 `disable_thinking:true`(或上游对应字段)动态开关推理。
|
||||
- **Lua 适配协议**:每个源挂一个 `.lua` 适配器,完成 `transform_request` /
|
||||
`transform_response` / `transform_stream_chunk` 双向转换,协议差异全在 Lua 层。
|
||||
@ -203,6 +211,33 @@ AUTO 调度**只**由优先级页保存的规则决定,源配置里的 `models
|
||||
- 同 tier 内按「偏好分」排序,失败槽位冷却后自动跳过;冷却 / 配额耗尽 / hard
|
||||
错误会顺延到下一 tier,全部失败时返回 503 并附上每档失败摘要。
|
||||
|
||||
### 冷却与半冷却探测(自愈调度)
|
||||
|
||||
槽位失败后进入指数退避冷却(5s → 10s → 20s …,上限 **5 分钟**)。冷却不是全时段
|
||||
硬闸:
|
||||
|
||||
- **前半段完全静默**:刚失败的槽位不接任何流量,避免对故障上游持续施压。
|
||||
- **后半段放行 1 个探测**:窗口过半后,同一 `(源, 模型)` 最多允许 **一个** 请求作为
|
||||
探测通过。探测槽数 = `clamp(max_concurrent / 10, 1, 2)`——`max_concurrent: 10`
|
||||
的源恰好放行 1 个探测请求。
|
||||
- **探测排在最后**:同 tier 内探测候选永远排在健康候选之后,只有没有正常槽可用时
|
||||
才承接真实流量,因此探测不会抢走可用容量。
|
||||
- **探测即真实请求**:成功则立即清零失败计数与冷却,槽位当场回到正常轮询——
|
||||
上游恢复/额度恢复后不必等满整个冷却窗口。失败则重开一个新窗口,下次探测顺延到
|
||||
新窗口的中点,不会连续重试。
|
||||
|
||||
分类冷却策略:
|
||||
|
||||
| 情况 | 冷却 | 说明 |
|
||||
|---|---|---|
|
||||
| 传输错误 / 5xx | 5s→10s→20s…,上限 5min | 指数退避 |
|
||||
| 401 / 403 凭据错误 | 10min | 换 key 后由下一次探测自动接回 |
|
||||
| 429 限流 | 30s 固定 | 「太快」不等于「坏了」,不进指数阶梯 |
|
||||
| 配额耗尽(`insufficient_quota` / `余额不足` 等) | 对齐配额窗口,上限 30min | **不进指数阶梯、不涨失败计数**,额度恢复即可用 |
|
||||
|
||||
WebUI「优先级」页的槽位健康标签会区分 `冷却` / `待探测` / `探测中`,悬停可看窗口
|
||||
起点、探测放行时刻与完全恢复时刻。
|
||||
|
||||
### 源(Source)与适配器(Adapter)的关系
|
||||
|
||||
- **源** 是到某个上游的连接描述:`name`、`base_url`、`api_key`、模型列表与优先级。
|
||||
@ -220,7 +255,7 @@ AUTO 调度**只**由优先级页保存的规则决定,源配置里的 `models
|
||||
2. `config.Load` 读取 `config.yaml`,`config.NewStore(runtime_file)` 读 WebUI 改动的
|
||||
运行时源,二者按名称合并成完整源列表。
|
||||
3. `rebuildRegistry` 为每个源创建 `provider.Provider`(持有目标适配器),并按源的
|
||||
并发上限配置适配器 worker 池大小。
|
||||
并发上限配置适配器 worker 池**上限**(不预分配,见下)。
|
||||
4. 请求进来时 `Registry` 按 `model` 路由到 Provider,Provider 调适配器
|
||||
`transform_request` → HTTP 发送 → `transform_response` / `transform_stream_chunk`。
|
||||
|
||||
|
||||
4
cmd/gui/package-lock.json
generated
4
cmd/gui/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "modelrouter-gui",
|
||||
"version": "1.2.0",
|
||||
"version": "1.4.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "modelrouter-gui",
|
||||
"version": "1.2.0",
|
||||
"version": "1.4.0",
|
||||
"license": "Proprietary",
|
||||
"devDependencies": {
|
||||
"electron": "^33.0.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "modelrouter-gui",
|
||||
"version": "1.2.0",
|
||||
"version": "1.4.0",
|
||||
"description": "ModelRouter Desktop — embedded ModelRouter core with tray",
|
||||
"author": "ModelRouter",
|
||||
"main": "main.js",
|
||||
@ -22,7 +22,7 @@
|
||||
"build": {
|
||||
"appId": "com.modelrouter.gui",
|
||||
"productName": "ModelRouter",
|
||||
"linux": {
|
||||
"linux": {
|
||||
"target": [
|
||||
"deb",
|
||||
"rpm",
|
||||
@ -32,9 +32,9 @@
|
||||
"icon": "build/icon.png",
|
||||
"maintainer": "ModelRouter",
|
||||
"synopsis": "ModelRouter Desktop",
|
||||
"desktop": {
|
||||
"desktop": {
|
||||
"entry": {
|
||||
"StartupWMClass": "modelrouter-gui"
|
||||
"StartupWMClass": "modelrouter-gui"
|
||||
}
|
||||
},
|
||||
"extraResources": [
|
||||
|
||||
Reference in New Issue
Block a user