Files
GoProxy/POOL_DESIGN.md
isboyjc f03c3300b4 feat: implement custom proxy subscription management and enhance configuration
- 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.
2026-04-04 22:25:54 +08:00

9.1 KiB
Raw Blame History

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.jsonsync.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 所属订阅 ID0=免费)
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