
# 中转塔台 · Relay Tower
**给 Sub2API 中转站站长用的运维面板:盯上游倍率、涨价预警、主调出故障自动切换、手机 Telegram 一键切线、算清每个客户的用量和利润**
Upstream rate monitor & auto-failover console for Sub2API relay operators · Prompt Cache affinity · Telegram remote control
[](https://github.com/oisano11/relay-tower/actions/workflows/ci.yml)
[](LICENSE)
[](https://nodejs.org/)
[](docker-compose.yml)
[](https://claude.ai)
[](https://cursor.com)
[](CONTRIBUTING.md)
[](https://telegram.org)
[English](README_EN.md) · [简体中文](README.md) · [一句话看懂](#-一句话看懂) · [为什么选择本项目?](#️-为什么选择-中转塔台-relay-tower横向对比) · [核心特性](#-核心特性矩阵) · [系统架构](#️-系统架构) · [快速开始](#-快速开始) · [客户端接入](#-客户端无缝接入指南) · [常见问题](#-常见问题-faq) · [更新日志](CHANGELOG.md)
---
## 🎯 一句话看懂
**适合谁:** 运营 **Sub2API 中转站** 的站长。上游账号多、倍率会变、半夜可能出故障,又想用手机随时盯着。
**暂不支持:** 自己的站是 New-API 的,目前还用不了。
| 您遇到的麻烦 | 中转塔台怎么帮您 |
| :--- | :--- |
| 上游半夜悄悄涨价,发现时已经亏了一天 | 每 5 分钟比对一次上游倍率;涨价立刻弹窗并推送 Telegram,可一键切到更低价的备选账号 |
| 主调账号欠费、被封或假死,客户全在报错 | 主调欠费、连续失败或首字超时,自动切到副调;客户端地址不用改,后续请求直接走新账号 |
| 人在外面,想用手机切线 | Telegram 机器人:`/status` 看状态,`/switch` 点按钮切换;内网、没有公网 IP 也能用 |
| 不知道哪个客户、哪个模型在赚钱还是在亏钱 | 「用户财务」按客户和模型统计请求数、Token 和利润;亏损通道标红 |
| 多个账号来回分流,Prompt Cache 命中率掉下来 | 每个分组只让一个主调接单,其余冷备,减少跨通道分流 |
### 🖥️ 控制台一览
总览:按业务分组看每个账号是主调还是副调,进价、售价、毛利、余额和首字速度一目了然
用量与模型利润:每个客户请求了多少次、用了哪些模型和分组、赚了或亏了多少
自动切号:主调出故障时自动切到副调,充值恢复、验证通过后再切回
以上均为演示数据,不含任何真实账号或客户。
---
## 📖 项目简介
在当下的大模型(LLM)API 分发与中转站运营中,开发者与中转站运营者面临着几大核心痛点:
1. **上游悄悄调高倍率**:上游供应商可能在半夜或高峰期暗中上涨进货倍率,导致中转站产生巨额亏损;
2. **多渠道分流影响 Prompt Cache**:同一上下文在不同服务商或节点间分流,可能降低提示词缓存命中率,增加 Token 费用和延迟;
3. **突发断流与宕机无法离机切线**:深夜上游突然宕机或被封禁,运维无法立刻开电脑登录后台切换通道;
4. **客户端热切换成本高**:传统中转系统切换渠道需要客户端重启或重新配置。
**中转塔台 (Relay Tower)** 是开源大模型中转网关与监控调度系统,包含**上游倍率监控**、**统一反向代理网关 (`/v1`)**、**Telegram 手机端切线机器人**以及 **Sub2API 容器化部署配置**。
---
## ⚖️ 为什么选择 中转塔台 (Relay Tower)?(横向对比)
| 功能特性 / 考量维度 | 传统反代 (Nginx / Caddy) | 原生 One-API / New-API | **中转塔台 (Relay Tower) (本项目)** |
| :--- | :---: | :---: | :---: |
| **上游进货倍率探针与差分感知** | ❌ 无感知 | ❌ 仅配置固定售价 | ✅ **定时探测与差分告警,默认每 5 分钟检查倍率** |
| **高危涨价强告警与备选熔断** | ❌ 无告警 | ❌ 无告警 | ✅ **主力涨价声光+Telegram强提醒,一键切至低价备选** |
| **Prompt Cache 单主路由亲和** | 取决于路由配置 | 取决于路由配置 | ✅ **适用分组维持冷备,减少跨通道分流** |
| **Telegram 手机端双向交互切线** | ❌ 无 | ❌ 仅单向被动推送 | ✅ **手机端弹出 Inline Keyboard,点击按钮秒级切线** |
| **统一入口切换 (`/v1`)** | 取决于配置 | 取决于配置 | ✅ **切换后续请求的上游,无需修改客户端入口** |
| **首字延迟 (TTFT) 超时智能熔断** | ❌ 仅能检测 HTTP 5xx | ❌ 仅检测普通超时 | ✅ **统计真实流式首字耗时,自动熔断假死/断流通道** |
| **商业进销利差与毛利率大盘** | ❌ 无 | ❌ 仅统计用户用量 | ✅ **实时计算各上游毛利差与利润率,标红亏损通道** |
| **内网穿透 / 免公网 IP 离机运维** | ❌ 需公网与 SSL 证书 | 需公网后台访问 | ✅ **Telegram Bot 采用 Long Polling,内网也能直接操控** |
---
## ✨ 核心特性矩阵
### 1. 📊 实时上游倍率大盘与智能探针
- **成本倍率即时透视**:支持自动对接主流 New-API / One-API `/api/pricing` 价格探针,实时大盘呈现各渠道最新进货倍率(如 `0.65x`, `0.85x`, `1.10x`)。
- **网络延迟与真实连通性探活**:周期性向各上游渠道发起轻量探针,毫秒级反馈延迟(ms)与健康状态。
- **进销毛利动态核算**:结合终端销售分组倍率,自动核算毛利差(Spread)与利润率(Margin %),实时高亮亏损通道。
### 2. 🚨 差分调价感知与高危涨价强告警
- **定时差分检测**:每轮倍率检查比较变化幅度(如 `0.65x -> 1.10x (+69.2%)`),默认周期为 5 分钟;通道探活默认每 3 小时执行,可手动触发检查。检测速度受周期及上游响应影响。
- **全维度立体报警**:屏幕居中强警示弹窗 + Web Audio 合成声效警报 + 完整调价审计日志。
- **主力通道涨价一键熔断**:当正在出海的主力通道被上游暗度陈仓涨价时,系统自动触发红色高危警报,并在消息界面提供“一键切换到更低倍率备选通道”快捷按钮。
### 3. 🔒 单主调独占与 Prompt Cache 路由亲和
- **减少双开分流**:适用分组保留一个主调,同组独立通道设为冷备 (`schedulable=false, priority=10`);跨组共享渠道自动保留全局调度开关,仅调低组内优先级 (`priority=10`),杜绝跨组误杀,完全支持一个渠道挂载多个业务分组。
- **缓存亲和**:尽量将后续请求交给同一上游通道,减少跨通道分流。上游仍可在内部调度不同实例;实际缓存命中率和节省金额取决于上游缓存策略、请求内容与有效期,不保证物理实例固定或特定命中率。
- **原子互斥交接**:切线操作(手动切换或自动熔断)执行原子 SQL 事务,瞬间关停旧主调、激活新主调,切线瞬间零分流冗余。
### 4. ⚡ 统一反向代理网关 (Smart Proxy Gateway)
- **统一接入终结点**:对外开放统一端口 `http://localhost:3300/v1`。
- **统一入口切换**:客户端(Claude Code CLI、Cursor、CC Switch、Chatbox、NextChat)配置此端口后,无需修改入口即可让后续请求使用新主调。已有请求不会迁移,故障请求仍可能需要重试。
- **🛡️ 专属网关密钥鉴权 (Gateway Key)**:外部请求调用 `/v1/*` 强制校验 `Authorization: Bearer ` 或 `x-api-key`,杜绝未授权外部访问盗刷上游高价值商业 Token;本地回环 (`127.0.0.1`) 自动放行。密钥可在中控台【安全设置】随时查看、复制与重置。
- **⚡ 标准 HTTP 502/503 异常透传**:彻底杜绝 Mock 伪造 200 假响应。上游连接失败返回 `502 Bad Gateway`,无可用上游返回 `503 Service Unavailable`,确保客户端自动触发错误重试。
- **🔒 独家单主 Prompt Cache 排他保护**:即使开启按成本自动准入,系统亦自动保留副调与备用渠道的冷备状态 (`schedulable=false`),避免多节点轮询导致缓存击穿。
- **💾 操作系统级原子写盘**:配置持久化采用 `.tmp` + `renameSync` 原子替换,规避高并发和异常关机时的 JSON 文件截断风险。
- **内置代理分流验证器**:中控台内嵌真实请求测试器,可随时模拟客户端调用,即时核验当前生效通道的分流效果。
### 5. ✈️ Telegram 机器人离机中控 (Telegram Bot Remote Console)
- **离机实时预警推送**:
- 上游进货倍率变动实时告警(附带涨跌百分比与变动渠道);
- 主力通道涨价高危警报(消息底部附带低价备用线路的 **一键切换交互按钮**);
- 首字延迟 (TTFT) 超时熔断或上游宕机切线报告。
- **手机端双向交互与一键切线**:
- `/status`:查看当前主力通道、进货倍率、销售毛利率、延迟与自动切线状态;
- `/switch`:弹出所有上游通道的 **Inline Keyboard 点击交互按钮**,在手机上点击任意渠道秒级完成调度切线;
- `/auto`:在手机上一键开关自动切线保护,或切换成本优先/极速优先策略;
- `/rates`:输出所有上游渠道进货倍率从低到高天梯榜;
- `/check`:立即发起全量上游价格探针与测速巡检。
- **长轮询架构**:采用 Long Polling 机制,内网、本地 Docker、无公网 IP VPS 均无需域名或 SSL 证书即可开箱即用。
### 6. 🛡️ 自动化故障转移与首字延迟 (TTFT) 熔断
- 实时统计真实流式请求的建立时间与首字时间(Time to First Token)。当检测到通道故障、5xx 错误超标或首字等待超时(TTFT Spike)时,自动平滑转移至备选候选池。
---
## 🏗️ 系统架构
```mermaid
flowchart TD
subgraph Clients["客户端与开发者工具 (Developer Clients)"]
C1["Claude Code CLI"]
C2["Cursor / VS Code"]
C3["CC Switch / Chatbox"]
C4["OpenAI / Anthropic SDK"]
end
subgraph Gateway["智能调度与监控中枢 (Upstream Monitor: 3300)"]
Proxy["⚡ 统一反向代理网关 (/v1)"]
CacheLock["🔒 Prompt Cache 独占锁引擎"]
Engine["🧠 自动调度与 TTFT 熔断引擎"]
Probe["🔍 上游倍率与延迟定时探针"]
Dashboard["💻 响应式 Web 中控台大盘"]
end
subgraph Control["控制平面 (Remote Control)"]
TG["✈️ Telegram Bot (双向交互与一键切线)"]
Admin["👤 管理员浏览器控制台"]
end
subgraph Core["底层路由与账本 (Sub2API 容器集群)"]
S2A["Sub2API 核心服务 (8080)"]
PG[("PostgreSQL 数据库")]
RD[("Redis 缓存集群")]
end
subgraph Upstreams["上游渠道池 (Upstream Channels)"]
U1["OpenAI 官方直连 / Azure"]
U2["Anthropic 优质专线"]
U3["DeepSeek / 第三方聚合源 A"]
U4["低价备用冷备渠道 B"]
end
Clients -->|API 请求| Proxy
Proxy -->|请求转发| Upstreams
Probe -->|定时探测价格与延迟| Upstreams
Probe --> Engine
Engine --> CacheLock
CacheLock -->|单主严格独占 / 互斥切线| Proxy
Engine -->|告警推送| TG
TG -->|/switch 交互指令| Engine
Admin --> Dashboard
Dashboard --> Proxy
Proxy -.->|可选直连或账号同步| S2A
S2A --> PG
S2A --> RD
```
---
## 📂 项目模块结构
```
├── 🚀 upstream-monitor/ # 核心系统:上游监控中枢与调度网关
│ ├── public/ # 现代化响应式 Web UI (大盘看板、策略面板、在线调试器)
│ ├── server.js # 统一智能反代 (/v1)、故障熔断与多维巡检调度核心
│ ├── telegram.js # Telegram 离机报警与移动端双向交互中控 Bot (长轮询免公网IP)
│ ├── auth.js # PBKDF2 安全认证、会话持久化与防暴力破解层
│ ├── Dockerfile # 监控中枢容器构建文件
│ └── data/ # 示例配置模板
│ ├── channels.example.json # 示例渠道配置
│ ├── telegram_config.example.json # 示例 Telegram 配置
│ └── auto_switch_config.example.json # 示例切线策略配置
├── 🐳 docker-compose.yml # 全栈容器化一键部署 (Sub2API + PG + Redis + Monitor)
├── ⚙️ .env.example # 根目录全局环境变量配置模板
├── 📖 CONTRIBUTING.md # 社区贡献指南与规范
├── 🛡️ SECURITY.md # 安全责任披露策略
└── 📄 LICENSE # MIT 开源协议
```
---
## 🚀 快速开始
### 方式一:Docker Compose 一键全栈部署(推荐)
只需 3 步,拉起包含数据库、Redis、Sub2API 路由与 Upstream Monitor 的全套生产系统:
```bash
# 1. 克隆仓库
git clone https://github.com/oisano11/relay-tower.git
cd relay-tower
# 2. 准备配置文件
cp .env.example .env
cp upstream-monitor/.env.example upstream-monitor/.env
# 3. 启动所有容器服务
docker-compose up -d
```
启动完成后,直接在浏览器中访问:
- **监控与调度中控台**:`http://localhost:3300`
- **统一 API 代理终结点**:`http://localhost:3300/v1`
- **Sub2API 核心后台**:`http://localhost:8080`
---
### 方式二:独立运行监控中枢 (Node.js)
如果您已有正在运行的 New-API、One-API 或第三方中转服务,只想单独使用 **Upstream Monitor 调度监控中枢**:
```bash
cd upstream-monitor
# 1. 安装轻量依赖
npm install
# 2. 初始化配置模板
cp .env.example .env
cp data/channels.example.json data/channels.json
cp data/telegram_config.example.json data/telegram_config.json
cp data/auto_switch_config.example.json data/auto_switch_config.json
# 3. 启动服务
node server.js
# 或使用自带脚本
./scripts/start.sh
```
打开浏览器访问 `http://localhost:3300`,终端将在首次启动时输出安全管理员密码。
---
## 💻 客户端无缝接入指南
将常用 AI 工具的 Base URL 指向中控台网关 `http://localhost:3300/v1`,即可使用缓存路由亲和与统一入口切换。
> [!TIP]
> **网关密钥获取**:示例中的 `sk-your-relay-key` 为网关接入密钥(Gateway API Key),可在控制台右上角【⚙️ 系统管理 → 🛡️ 安全设置与改密】中一键查看、复制或重置。若客户端与服务部署在同一台机器通过 `127.0.0.1` 访问,系统默认免密放行。
### 1. Claude Code CLI
```bash
export ANTHROPIC_BASE_URL="http://localhost:3300"
export ANTHROPIC_API_KEY="sk-your-relay-key"
claude
```
### 2. Cursor / VS Code
- **OpenAI Base URL**: `http://localhost:3300/v1`
- **API Key**: `sk-your-relay-key`
- 开启支持 Claude 3.7 Sonnet / DeepSeek V3 等任意模型。
### 3. Python (OpenAI SDK)
```python
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:3300/v1",
api_key="sk-your-relay-key"
)
response = client.chat.completions.create(
model="claude-3-7-sonnet-20250219",
messages=[{"role": "user", "content": "你好,请介绍一下 Prompt Cache 的优势!"}]
)
print(response.choices[0].message.content)
```
### 4. Node.js / TypeScript
```typescript
import OpenAI from 'openai';
const openai = new OpenAI({
baseURL: 'http://localhost:3300/v1',
apiKey: 'sk-your-relay-key',
});
async function main() {
const completion = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Ping!' }],
});
console.log(completion.choices[0].message.content);
}
main();
```
### 5. cURL 快速验证
```bash
curl http://localhost:3300/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-relay-key" \
-d '{
"model": "claude-3-7-sonnet-20250219",
"messages": [{"role": "user", "content": "Hello!"}]
}'
```
---
## ✈️ Telegram 机器人配置与使用说明
### 1. 获取 Bot Token
1. 在 Telegram 中搜索 `@BotFather`;
2. 发送 `/newbot` 指令,按照指引输入机器人名称与用户名;
3. 获取形如 `123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ` 的 API Token;
4. 将 Token 填入中控台 **Telegram 设置** 弹窗中,或配置在环境变量 `TELEGRAM_BOT_TOKEN` 中。
### 2. 管理员一键免密绑定
- 在 Telegram 中私聊机器人,使用 `/bind <控制台管理密码>` 绑定,或在控制台配置管理员个人 Telegram ID;
- `/start` 不会自动授予管理员权限。通知群仅接收消息,加入通知群不会使群成员获得操作权限。
### 3. 指令速查表
| 指令 | 说明 | 交互效果 |
| :--- | :--- | :--- |
| `/status` | 汇报当前主力大盘 | 输出主力渠道、进货倍率、销售毛利率、延迟、Prompt Cache 状态 |
| `/switch` | 快速切线交互面板 | 弹出全渠道 **Inline Keyboard 交互按钮**,在手机上一键秒切 |
| `/auto` | 自动切换保护管理 | 在手机上一键开关自动故障转移与 TTFT 熔断保护 |
| `/rates` | 倍率天梯排行榜 | 输出所有可用上游渠道的进货倍率天梯榜(从低到高排序) |
| `/check` | 立即发起全盘巡检 | 触发后台向所有上游执行测速与价格差分探测 |
---
## ⚙️ 环境变量配置参考
### 全局根目录 (`.env`)
| 环境变量 | 默认值 | 说明 |
| :--- | :--- | :--- |
| `BIND_HOST` | `0.0.0.0` | 服务绑定 IP |
| `SERVER_PORT` | `8080` | Sub2API 服务端口 |
| `POSTGRES_PASSWORD` | - | PostgreSQL 数据库密码 (必填) |
| `REDIS_PASSWORD` | - | Redis 缓存密码 |
| `JWT_SECRET` | - | 登录会话签名 Secret (建议 `openssl rand -hex 32`) |
| `ADMIN_EMAIL` | `admin@example.com`| 初始超级管理员邮箱 |
| `ADMIN_PASSWORD` | - | 初始超级管理员密码 |
| `MONITOR_PORT` | `3300` | 监控中控台对外端口 |
### 监控中枢 (`upstream-monitor/.env`)
| 环境变量 | 默认值 | 说明 |
| :--- | :--- | :--- |
| `PORT` | `3300` | 监控中控台与代理服务端口 |
| `ADMIN_PASSWORD` | 随机生成 | 控制台登录管理密码(首次运行控制台输出) |
| `TELEGRAM_BOT_TOKEN` | - | Telegram Bot 凭证 (可选) |
| `IS_VPS` | `false` | 是否与数据库处于同机 Docker 环境 |
| `SSH_HOST` | - | 若连接远程宿主机数据库容器,配置远程 SSH 地址 |
---
## ❓ 常见问题 (FAQ)
### Q1: 为什么要开启“单主调严格独占”?它如何保护 Prompt Cache?
> **答**:单主调减少跨上游通道分流,有助于保持缓存亲和性。系统完全支持一个渠道属于多个业务组,对跨组共享账号智能保留全局调度开关并仅降级组内优先级,防止误杀其他分组。
### 当前架构边界
数据库和 Redis 同步仍包含同步子进程调用,慢查询或 SSH 等待可能阻塞网关事件循环。异步数据库访问、后台任务与网关分进程属于后续架构工作。本次修复计划与验收范围见 [修复计划](docs/repair-plan.md);镜像启动检查已加入 CI,实际部署需以运行结果为准。
### Q2: Telegram 机器人需要公网 IP 或独立域名吗?
> **答**:**完全不需要!** 机器人采用官方推荐的 `Long Polling`(长轮询)机制,只要运行机器能访问外网(支持配置 HTTP/SOCKS5 代理),即使部署在本地内网电脑、NAT 家宽或无公网 IP 的容器中,也能随时向你的手机推送报警并接收交互指令。
### Q3: 现有生产中转站如何平滑接入本项目?
> **答**:您可以仅部署 `upstream-monitor`。进入该目录执行 `node server.js`,通过中控台导入渠道配置,并将开发工具的 Base URL 切换为 `http://your-server:3300/v1`,即可使用倍率监控与统一入口切线。迁移前应确认客户端兼容性及所需数据库连接。
---
## 🤝 参与贡献
我们极其欢迎社区贡献!无论是新特性建议、Bug 反馈还是文档优化:
1. 提交前请阅读 [CONTRIBUTING.md](CONTRIBUTING.md);
2. 遵守安全责任披露策略 [SECURITY.md](SECURITY.md);
3. 遵循 Conventional Commits 规范提交 PR。
---
## 📄 开源许可证
本项目基于 [MIT License](LICENSE) 开源发布。自由使用,商业与个人友好。
---
**关键词:** Sub2API 中转站运维 · 上游倍率监控 · 涨价预警 · 主调故障自动切换 · Telegram 机器人切线 · New-API / One-API 上游 · Prompt Cache 路由亲和 · Claude Code / Cursor 统一入口 · LLM gateway failover