mirror of
https://github.com/isboyjc/GoProxy.git
synced 2026-05-06 20:02:54 +08:00
- Added support for importing Clash/V2ray subscriptions, including automatic format detection and integration with sing-box for protocol conversion. - Introduced five proxy usage modes in the configuration, allowing flexible selection between mixed, custom-only, and free-only modes. - Enhanced `.env.example` and `docker-compose.yml` to include new environment variables for custom proxy settings. - Updated `CHANGELOG.md` to document new features and improvements related to subscription management. - Improved WebUI for managing subscriptions and displaying proxy statistics. - Implemented a background process for refreshing subscriptions and probing disabled proxies for reactivation.
9.1 KiB
9.1 KiB
GoProxy 架构设计
系统概览
GoProxy 是一个单二进制的智能代理池系统,由多个协作的 goroutine 组成。核心设计理念:免费池自动运转 + 订阅池按需导入,两池独立管理但统一对外服务。
┌─────────────────────────┐
│ WebUI (:7778) │
│ 管理面板 / 订阅管理 / 设置 │
└──────────┬──────────────┘
│
┌──────────────────┐ ┌──────────┴──────────────┐ ┌──────────────────┐
│ 免费代理源 (20+) │──▶│ SQLite 代理池 │◀──│ 订阅源 (Clash/ │
│ 公开列表自动抓取 │ │ proxies / subscriptions │ │ V2ray/Base64) │
└──────────────────┘ └──────────┬──────────────┘ └──────────────────┘
│ │
┌──────────┴──────────────┐ ┌───────┴────────┐
│ 对外代理服务 │ │ sing-box │
│ HTTP (:7776 / :7777) │ │ 协议转换进程 │
│ SOCKS5 (:7779 / :7780) │ │ vmess/trojan │
└───────────────────────────┘ │ → local socks5│
└────────────────┘
模块依赖
main.go (orchestrator)
├── config/ 配置管理(环境变量 + config.json),sync.RWMutex 线程安全
├── storage/ SQLite 持久化(proxies + subscriptions + source_status)
├── fetcher/ 免费代理抓取(20+ 源,断路器保护)
├── validator/ 代理验证(连接 + 出口 IP + 地理位置 + 延迟 + HTTPS 隧道)
├── pool/ 池子管理(slot 准入、替换逻辑、状态机)
├── checker/ 健康检查(批次验证,free 删除 / custom 禁用)
├── optimizer/ 质量优化(替换慢代理,仅作用于免费池)
├── custom/ 订阅管理
│ ├── parser.go 格式自动识别(Clash YAML / V2ray 链接 / Base64 / 纯文本)
│ ├── singbox.go sing-box 进程管理(配置生成 + 启停 + 端口映射)
│ └── manager.go 刷新循环 + 探测唤醒 + 过期清理
├── proxy/ 对外代理服务
│ ├── server.go HTTP 代理(支持 CONNECT 隧道)
│ └── socks5_server.go SOCKS5 代理(原生协议实现)
├── webui/ 管理面板(嵌入式 HTML + REST API)
└── logger/ 内存日志收集(供 WebUI 展示)
数据模型
proxies 表
| 字段 | 类型 | 说明 |
|---|---|---|
| address | TEXT UNIQUE | 代理地址 (host:port) |
| protocol | TEXT | http / socks5 |
| source | TEXT | free / custom |
| subscription_id | INTEGER | 所属订阅 ID(0=免费) |
| exit_ip | TEXT | 出口 IP |
| exit_location | TEXT | "国家代码 城市" |
| latency | INTEGER | 延迟 (ms) |
| quality_grade | TEXT | S(<=500ms) / A(<=1000) / B(<=2000) / C(>2000) |
| status | TEXT | active / degraded / disabled / candidate_replace |
| fail_count | INTEGER | 连续失败次数 |
| use_count / success_count | INTEGER | 使用统计 |
subscriptions 表
| 字段 | 类型 | 说明 |
|---|---|---|
| url | TEXT | 订阅 URL |
| file_path | TEXT | 本地文件路径 |
| format | TEXT | auto(全自动识别) |
| status | TEXT | active / paused |
| last_fetch | DATETIME | 最后拉取时间 |
| last_success | DATETIME | 最后有可用节点的时间 |
| contributed | INTEGER | 是否为访客贡献 |
免费池状态机
总量>95%
┌─────────────────────────────────────┐
│ ▼
┌──────┐ 总量<95% ┌─────────┐ 协议<20% ┌──────────┐ 缺失协议或<10% ┌───────────┐
│HEALTHY│──────────▶│ WARNING │───────────▶│ CRITICAL │─────────────────▶│ EMERGENCY │
└──────┘ └─────────┘ └──────────┘ └───────────┘
各状态对应的行为:
| 状态 | 延迟阈值 | 抓取模式 | 说明 |
|---|---|---|---|
| healthy | 2000ms | 不抓取 | 优化器定期替换慢代理 |
| warning | 4000ms | refill (快源) | 补充到 95% |
| critical | 4000ms | refill (快源) | 优先补充缺失协议 |
| emergency | 4000ms | emergency (全源) | 忽略断路器,全力抓取 |
订阅池生命周期
添加订阅 → 验证(拉取+解析) → 入库
│
┌───────────────────────┘
▼
刷新订阅(定时/手动)
│
├── 拉取内容(直连 → 代理 fallback)
├── 自动识别格式
├── 删除该订阅旧代理
├── 分类节点
│ ├── HTTP/SOCKS5 → 直接入池
│ └── vmess/trojan/... → sing-box 转换 → 本地 SOCKS5 入池
├── 验证入池代理(含地理过滤)
│ ├── 通过 → status=active, 更新 last_success
│ └── 失败/被过滤 → status=disabled
└── 更新订阅 proxy_count
探测唤醒
每 N 分钟(默认 10)
│
├── 获取所有 source=custom AND status=disabled 的代理
├── 逐个验证
│ ├── 通过 + 未被地理过滤 → EnableProxy → 更新 last_success
│ └── 失败 或 被地理过滤 → 保持 disabled
└── 日志输出恢复数量
自动清理
每分钟检查:创建超过 7 天且 last_success 距今超过 7 天的订阅 → 删除订阅 + 关联代理 + 重建 sing-box。
代理选择策略
5 种模式通过 CustomProxyMode + CustomPriority + CustomFreePriority 三个配置组合:
| UI 选项 | Mode | Priority | FreePriority | 选择逻辑 |
|---|---|---|---|---|
| 混合·订阅优先 | mixed | true | false | 先 custom,无可用 fallback 全部 |
| 混合·免费优先 | mixed | false | true | 先 free,无可用 fallback 全部 |
| 混合·平等 | mixed | false | false | sourceFilter="",不区分来源 |
| 仅订阅 | custom_only | - | - | sourceFilter="custom" |
| 仅免费 | free_only | - | - | sourceFilter="free" |
HTTP 代理服务可使用 HTTP 或 SOCKS5 上游代理。SOCKS5 代理服务仅使用 SOCKS5 上游代理。
sing-box 集成
订阅节点 (vmess/vless/trojan/ss/hysteria2/anytls)
│
▼
生成 sing-box JSON 配置:
inbounds: 每个节点一个本地 SOCKS5 端口 (20001, 20002, ...)
outbounds: 每个节点对应一个加密协议出站
route: inbound → outbound 一一映射
│
▼
启动 sing-box 子进程 (sing-box run -c config.json)
│
▼
本地 socks5://127.0.0.1:20001 ... 入池为 source=custom 代理
Docker 镜像自带 sing-box 二进制,支持 amd64/arm64。本地运行需手动安装。
后台 Goroutine
| Goroutine | 间隔 | 职责 |
|---|---|---|
| 状态监控 | 30s | 检查免费池状态,触发 smartFetchAndFill |
| 健康检查 | 5min | 批量验证代理,free 删除 / custom 禁用 |
| 优化轮换 | 30min | 替换免费池中的慢代理 |
| 订阅刷新 | 1min tick | 检查到期订阅,执行刷新 |
| 探测唤醒 | 10min | 探测 disabled 的订阅代理 |
| 配置监听 | event | WebUI 配置变更后调整 slot |
地理过滤
全局生效,对两个池子行为不同:
| 操作 | 免费代理 | 订阅代理 |
|---|---|---|
| 启动清理 | DELETE | status → disabled |
| 验证时不通过 | 不入池 | 入池但 disabled |
| 探测唤醒 | - | 被过滤的不启用 |
| 配置变更 | 下次清理生效 | 下次清理生效 |
白名单(AllowedCountries)优先于黑名单(BlockedCountries)。
端口映射
| 端口 | 服务 | 模式 |
|---|---|---|
| 7776 | HTTP 代理 | 最低延迟 |
| 7777 | HTTP 代理 | 随机轮换 |
| 7778 | WebUI | 管理面板 |
| 7779 | SOCKS5 代理 | 随机轮换 |
| 7780 | SOCKS5 代理 | 最低延迟 |
| 20001+ | sing-box 本地 | 仅 127.0.0.1 |