Files

352 lines
29 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第六部分:智能调度系统
## 6.1 实时链路探测
```
┌──────────────────────────────────────────────────────────────────┐
│ 实时链路探测系统 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 探测架构: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 探测集群 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 探测节点 │ │ 探测节点 │ │ 探测节点 │ ... │ │
│ │ │ (北京) │ │ (上海) │ │ (广州) │ │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │
│ │ │ │ │ │ │
│ │ └──────────────┴──────────────┘ │ │
│ │ │ │ │
│ │ ┌──────┴──────┐ │ │
│ │ │ 数据汇聚 │ │ │
│ │ │ (ClickHouse)│ │ │
│ │ └──────┬──────┘ │ │
│ │ │ │ │
│ │ ┌──────┴──────┐ │ │
│ │ │ 分析引擎 │ │ │
│ │ │ (实时计算) │ │ │
│ │ └──────┬──────┘ │ │
│ │ │ │ │
│ │ ┌──────┴──────┐ │ │
│ │ │ 调度决策 │ │ │
│ │ │ (路由更新) │ │ │
│ │ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 探测指标: │
│ ┌──────────────┬──────────────┬──────────────┬──────────────┐ │
│ │ 指标 │ 方法 │ 频率 │ 精度 │ │
│ ├──────────────┼──────────────┼──────────────┼──────────────┤ │
│ │ Ping │ ICMP/UDP │ 每5秒 │ ±1ms │ │
│ │ Jitter │ RTT标准差 │ 每5秒 │ ±2ms │ │
│ │ Loss │ 统计法 │ 每10秒 │ ±0.1% │ │
│ │ RTT │ TCP/UDP │ 每5秒 │ ±1ms │ │
│ │ Bandwidth │ 递增探测 │ 每分钟 │ ±10% │ │
│ │ Node Load │ 心跳上报 │ 每10秒 │ ±5% │ │
│ └──────────────┴──────────────┴──────────────┴──────────────┘ │
│ │
│ 探测数据存储: │
│ - 实时数据:Redis(最新值,TTL 5分钟) │
│ - 历史数据:ClickHouse(聚合后,保留30天) │
│ - 告警数据:MySQL(持久化) │
│ │
└──────────────────────────────────────────────────────────────────┘
```
## 6.2 调度算法设计
### 6.2.1 基础版本(规则引擎)
```
┌──────────────────────────────────────────────────────────────────┐
│ 基础调度算法(规则引擎) │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 输入: │
│ - 用户位置(城市、ISP) │
│ - 游戏服务器位置 │
│ - 节点列表及其状态 │
│ │
│ 输出: │
│ - 最优节点 │
│ - 路由路径 │
│ │
│ 规则优先级: │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 规则1:同城市同ISP → 直连 │ │
│ │ 条件:user.city == node.city && user.isp == node.isp │ │
│ │ 动作:直接选择该节点 │ │
│ │ 优先级:1(最高) │ │
│ │ │ │
│ │ 规则2:同城市跨ISP → BGP节点 │ │
│ │ 条件:user.city == node.city && user.isp != node.isp │ │
│ │ 动作:选择BGP节点 │ │
│ │ 优先级:2 │ │
│ │ │ │
│ │ 规则3:同区域跨城市 → 区域核心节点 │ │
│ │ 条件:user.region == node.region && user.city != node.city│ │
│ │ 动作:选择区域核心节点 │ │
│ │ 优先级:3 │ │
│ │ │ │
│ │ 规则4:跨区域 → 中转节点 │ │
│ │ 条件:user.region != node.region │ │
│ │ 动作:选择最优中转节点 │ │
│ │ 优先级:4 │ │
│ │ │ │
│ │ 规则5:跨境 → 国际专线节点 │ │
│ │ 条件:user.country != node.country │ │
│ │ 动作:选择国际专线节点 │ │
│ │ 优先级:5(最低) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ 伪代码实现: │
│ │
│ func basicSchedule(user *User, game *Game) *Node { │
│ candidates := getCandidateNodes(game) │
│ │
│ // 规则1:同城市同ISP │
│ for _, node := range candidates { │
│ if node.City == user.City && node.ISP == user.ISP { │
│ return node │
│ } │
│ } │
│ │
│ // 规则2:同城市BGP │
│ for _, node := range candidates { │
│ if node.City == user.City && node.IsBGP { │
│ return node │
│ } │
│ } │
│ │
│ // 规则3:同区域核心节点 │
│ for _, node := range candidates { │
│ if node.Region == user.Region && node.IsCore { │
│ return node │
│ } │
│ } │
│ │
│ // 规则4:中转节点 │
│ bestScore := 0.0 │
│ var bestNode *Node │
│ for _, node := range candidates { │
│ score := calculateScore(node, user) │
│ if score > bestScore { │
│ bestScore = score │
│ bestNode = node │
│ } │
│ } │
│ return bestNode │
│ } │
│ │
└──────────────────────────────────────────────────────────────────┘
```
### 6.2.2 高级版本(多因子加权)
```
┌──────────────────────────────────────────────────────────────────┐
│ 高级调度算法(多因子加权) │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 输入因子: │
│ ┌──────────────┬──────────┬──────────┬──────────────────────┐ │
│ │ 因子 │ 权重 │ 范围 │ 说明 │ │
│ ├──────────────┼──────────┼──────────┼──────────────────────┤ │
│ │ RTT │ 0.35 │ 0-500ms │ 往返延迟 │ │
│ │ Loss Rate │ 0.25 │ 0-100% │ 丢包率 │ │
│ │ Jitter │ 0.15 │ 0-100ms │ 抖动 │ │
│ │ Node Load │ 0.10 │ 0-100% │ 节点负载 │ │
│ │ ISP Match │ 0.05 │ 0/1 │ ISP匹配 │ │
│ │ Geo Distance │ 0.05 │ 0-10000km│ 地理距离 │ │
│ │ Line Quality │ 0.05 │ 0-1 │ 线路质量 │ │
│ └──────────────┴──────────┴──────────┴──────────────────────┘ │
│ │
│ 评分公式: │
│ │
│ Score(i) = Σ(Wj × normalize(Fij)) │
│ │
│ 其中: │
│ - Wj = 第j个因子的权重 │
│ - Fij = 节点i在第j个因子上的值 │
│ - normalize() = 归一化到[0,1]区间 │
│ │
│ 归一化方法: │
│ - RTT: norm = 1 - (RTT / max_RTT) │
│ - Loss: norm = 1 - Loss │
│ - Jitter: norm = 1 - (Jitter / max_Jitter) │
│ - Load: norm = 1 - Load │
│ - ISP Match: norm = 1 if match else 0 │
│ - Geo Distance: norm = 1 - (dist / max_dist) │
│ - Line Quality: norm = Quality_Score │
│ │
│ 伪代码实现: │
│ │
│ type ScheduleFactor struct { │
│ Name string │
│ Weight float64 │
│ MaxVal float64 │
│ } │
│ │
│ var factors = []ScheduleFactor{ │
│ {"rtt", 0.35, 500}, │
│ {"loss", 0.25, 1.0}, │
│ {"jitter", 0.15, 100}, │
│ {"load", 0.10, 1.0}, │
│ {"isp_match", 0.05, 1.0}, │
│ {"geo_dist", 0.05, 10000}, │
│ {"line_quality", 0.05, 1.0}, │
│ } │
│ │
│ func advancedSchedule(user *User, game *Game) *Node { │
│ candidates := getCandidateNodes(game) │
│ │
│ var bestNode *Node │
│ bestScore := -1.0 │
│ │
│ for _, node := range candidates { │
│ score := 0.0 │
│ │
│ // RTT因子 │
│ rttNorm := 1.0 - (node.RTT / 500.0) │
│ score += 0.35 * rttNorm │
│ │
│ // 丢包因子 │
│ lossNorm := 1.0 - node.LossRate │
│ score += 0.25 * lossNorm │
│ │
│ // 抖动因子 │
│ jitterNorm := 1.0 - (node.Jitter / 100.0) │
│ score += 0.15 * jitterNorm │
│ │
│ // 负载因子 │
│ loadNorm := 1.0 - node.LoadRate │
│ score += 0.10 * loadNorm │
│ │
│ // ISP匹配 │
│ ispNorm := 0.0 │
│ if node.ISP == user.ISP { │
│ ispNorm = 1.0 │
│ } │
│ score += 0.05 * ispNorm │
│ │
│ // 地理距离 │
│ dist := haversine(user.Lat, user.Lng, node.Lat, node.Lng)│
│ distNorm := 1.0 - (dist / 10000.0) │
│ score += 0.05 * distNorm │
│ │
│ // 线路质量 │
│ score += 0.05 * node.LineQuality │
│ │
│ if score > bestScore { │
│ bestScore = score │
│ bestNode = node │
│ } │
│ } │
│ │
│ return bestNode │
│ } │
│ │
└──────────────────────────────────────────────────────────────────┘
```
### 6.2.3 AI版本(机器学习)
```
┌──────────────────────────────────────────────────────────────────┐
│ AI调度算法(机器学习) │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 模型选择:XGBoost / LightGBM │
│ 原因: │
│ - 推理速度快(<1ms) │
│ - 可解释性好 │
│ - 特征重要性可分析 │
│ - 训练数据要求相对低 │
│ │
│ 特征工程: │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 用户特征: │ │
│ │ - user_city (one-hot编码) │ │
│ │ - user_isp (one-hot编码) │ │
│ │ - user_latency_avg (历史平均延迟) │ │
│ │ - user_loss_avg (历史平均丢包率) │ │
│ │ - user_bandwidth (用户带宽) │ │
│ │ - time_of_day (时段,0-23) │ │
│ │ - day_of_week (星期,0-6) │ │
│ │ - is_peak_hour (是否高峰时段) │ │
│ │ │ │
│ │ 节点特征: │ │
│ │ - node_city (one-hot编码) │ │
│ │ - node_isp (one-hot编码) │ │
│ │ - node_rtt (当前延迟) │ │
│ │ - node_loss (当前丢包率) │ │
│ │ - node_jitter (当前抖动) │ │
│ │ - node_load (当前负载) │ │
│ │ - node_bandwidth (节点带宽) │ │
│ │ - node_line_type (线路类型,0-5) │ │
│ │ │ │
│ │ 游戏特征: │ │
│ │ - game_id (游戏ID) │ │
│ │ - game_region (游戏区域) │ │
│ │ - game_protocol (游戏协议,TCP/UDP/混合) │ │
│ │ - game_server_distance (游戏服务器距离) │ │
│ │ │ │
│ │ 交叉特征: │ │
│ │ - user_node_distance (用户到节点距离) │ │
│ │ - user_node_isp_match (ISP是否匹配) │ │
│ │ - node_game_distance (节点到游戏服务器距离) │ │
│ │ - historical_score (历史评分) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ 标签: │
│ - 实际加速效果评分(0-100) │
│ - 用户满意度(点击"反馈"按钮) │
│ - 是否掉线(0/1) │
│ │
│ 训练流程: │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 数据收集 │───→│ 特征工程 │───→│ 模型训练 │ │ │
│ │ │ 30天数据 │ │ 特征提取 │ │ XGBoost │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │ │ │
│ │ │ ┌───────────────────┘ │ │
│ │ │ ↓ │ │
│ │ │ ┌──────────┐ ┌──────────┐ │ │
│ │ │ │ 模型评估 │───→│ 模型部署 │ │ │
│ │ │ │ A/B测试 │ │ 在线推理 │ │ │
│ │ │ └──────────┘ └──────────┘ │ │
│ │ │ │ │
│ │ └─── 每周重新训练,持续优化 │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ 推理流程: │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ func aiSchedule(user *User, game *Game) *Node { │ │
│ │ candidates := getCandidateNodes(game) │ │
│ │ │ │
│ │ // 提取特征 │ │
│ │ features := extractFeatures(user, candidates, game) │ │
│ │ │ │
│ │ // 模型推理 │ │
│ │ scores := model.Predict(features) │ │
│ │ │ │
│ │ // 选择最高分节点 │ │
│ │ bestIdx := argmax(scores) │ │
│ │ return candidates[bestIdx] │ │
│ │ } │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ A/B测试: │
│ - 10%用户使用AI调度 │
│ - 90%用户使用高级调度 │
│ - 对比指标:延迟、丢包率、用户满意度 │
│ - 显著提升后全量切换 │
│ │
└──────────────────────────────────────────────────────────────────┘
```