在线教学平台部署在香港服务器上,如何结合 BGP(CN2/CMIN2/CU/PCCW)多线带宽把国内和东南亚学生的延迟打下来
技术教程 2025-09-19 09:22 219


那天晚上 20:10,国内黄金时段。Zoom 与我们自己的 WebRTC 教学白板并行,直播间在线 2,300+。北方、电信线路的学生 RTT 突然从 55ms 抬到 180ms,丢包 8%~12%,老师的板书像 PPT 放映。家长在群里“???”,我在香港葵涌的机房边打 MTR 边换路由策略。最终靠把北区用户迅速切上 CN2、华东和华南用 CU/CMI、东南亚甩给 PCCW,10 分钟内稳定回 40~70ms。第二天起我决定彻底重构网络,把 BGP 多线玩到骨子里。

1. 目标与约束(SLO/SLA)

  • SLO(延迟):中国大陆与东南亚主要城市至香港边缘节点 P95 ≤ 80ms,P99 ≤ 120ms。
  • 丢包:峰值时段 P95 ≤ 0.5%,P99 ≤ 1%。
  • 并发:实时互动课 5,000 WebRTC 会话,旁路 HLS/LL-HLS 回放峰值 20 Gbps。
  • 合规/运维:CentOS 7 环境、灰度可回滚、95 分计费成本可控。

2. 机房与硬件选型(真实参数表)

项目 选择 说明
机房 香港荃湾/葵涌双点 同城双活,延迟 < 0.3ms
边缘网关 2× Dell R6525 (EPYC 7543) 32C/64T,128GB,双 25GbE (Mellanox CX4-Lx)
媒体节点(SFU) 6× R7525 (EPYC 7B13) 64C/128T,256GB,2× 3.2TB NVMe (OSD/回放缓存)
存储/回放 Ceph 3 副本 + Nginx-OSS 缓存 回放与课件
交换机 2× 25G ToR(VSX) 上联 2×100G 至核心
带宽 BGP 混合:CN2 / CMIN2 / CU / PCCW 各 10G 起步,按 95 分升级
任播 Anycast / GeoDNS 混合 控 inbound,结合上游社区策略
操作系统 CentOS 7 + ELRepo Kernel 5.10 为 BBR/多队列与 XDP 做准备

注:如果没有自有 ASN 与跨运营商的上游会话,也可以采购“BGP 多线优化”带宽产品,让上游代持 BGP;我们同时在出口网关上做策略路由 + GeoDNS,把可控的那一段做到最好。

3. 拓扑与路由思路(简单画)

[学生端 CN/SEA] 
     |  (GeoDNS/Anycast)
   Internet
     |
 [HK 边缘网关集群]  --- BGP --  CN2
     |               --- BGP --  CMIN2
     |               --- BGP --  CU
     |               --- BGP --  PCCW
 [SFU/媒体]---[回放缓存]---[对象存储]
     |
 [监控/日志/告警]
  • Inbound(入向):用 GeoDNS 将国内北区偏向 CN2、南区/华东偏 CU/CMI;SEA 国家(SG/MY/TH/VN/ID/PH)偏 PCCW/CMI。
  • Outbound(出向):网关上用策略路由(ip rule + fwmark)把特定国家/AS 的流量分别走对应出口;BGP 上用 local-preference + 社区(由上游约定)微调。

4. 系统层优化(CentOS 7 环境)

4.1 升级内核至 5.x 并启用 BBR

# 1) 安装 ELRepo 内核
yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
yum --enablerepo=elrepo-kernel install -y kernel-ml

# 2) 设为默认
grub2-set-default 0 && grub2-mkconfig -o /boot/grub2/grub.cfg

# 3) 启用 BBR 与队列优化
cat >> /etc/sysctl.d/99-net-tune.conf <<'EOF'
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 250000
net.ipv4.ip_local_port_range = 10000 65000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_syn_retries = 6
net.ipv4.tcp_slow_start_after_idle = 0
net.netfilter.nf_conntrack_max = 4194304
net.netfilter.nf_conntrack_tcp_timeout_established = 300
EOF
sysctl --system

4.2 NIC 与中断亲和

# 多队列开启与中断亲和
ethtool -L eth0 combined 32
systemctl enable irqbalance --now
# RPS/XPS(按 CPU 拓扑调优)
echo ffffffff > /sys/class/net/eth0/queues/rx-0/rps_cpus
echo 4096      > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt

5. 出口网关的路由策略(FRR + 策略路由)

有 ASN 就跑 eBGP;没有也能让上游发静态缺省过来,我们内部再做 PBR。

5.1 FRR(bgpd)样例

/etc/frr/daemons 开启 bgpd,然后:

vtysh
configure terminal
router bgp 65001
 bgp router-id 203.0.113.2

# CN2 上游
 neighbor 203.0.113.9 remote-as 4809
 neighbor 203.0.113.9 description CN2-Upstream
 address-family ipv4 unicast
  neighbor 203.0.113.9 activate
  neighbor 203.0.113.9 route-map PREF-CN2 in
 exit-address-family

# CMIN2 上游
 neighbor 198.51.100.9 remote-as 58453
 neighbor 198.51.100.9 description CMIN2-Upstream
 address-family ipv4 unicast
  neighbor 198.51.100.9 activate
  neighbor 198.51.100.9 route-map PREF-CMI in
 exit-address-family

# CU/PCCW 同理...

route-map PREF-CN2 permit 10
 set local-preference 200
!
route-map PREF-CMI permit 10
 set local-preference 180
!
end
write

解释:我们给 CN2 提高 local-preference,让对国内方向更倾向 CN2;SEA 方向则在上游或 GeoDNS 层面命中 PCCW/CMI。部分上游支持社区值来“偏好省网/骨干/低拥塞”,这属于商业约定,我在这里不写死数值,按你的上游文档填写。

5.2 基于国家/AS 的策略路由(不改应用)

核心做法:ipset 存放 CN/SEA 的网段或 AS 归属,mangle 表打 mark,ip rule 走不同路由表。

# 1) 创建 ipset(示例:CN、SEA 若干国)
ipset create GEO_CN hash:net
ipset create GEO_SEA hash:net
# 导入你从 GeoLite/企业库生成的 CN/SEA 网段列表
# ipset add GEO_CN 1.2.0.0/16  ...(略)

# 2) 打 mark
iptables -t mangle -A PREROUTING -m set --match-set GEO_CN src -j MARK --set-mark 10
iptables -t mangle -A PREROUTING -m set --match-set GEO_SEA src -j MARK --set-mark 20

# 3) 建路由表
ip route add default via 203.0.113.1 dev eth0 table 10   # CN2
ip route add default via 198.51.100.1 dev eth1 table 20  # PCCW/CMI

# 4) 规则关联
ip rule add fwmark 10 table 10
ip rule add fwmark 20 table 20

小坑:如果你有 GRE/IPIP 隧道(某些上游会给),记得 MSS Clamping:

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
  -j TCPMSS --clamp-mss-to-pmtu

6. 传输与应用层:WebRTC + 回放并行优化

6.1 WebRTC(SFU:mediasoup/Janus 任选)

  • 编解码:H.264 baseline / Opus,避免部分国产浏览器的 VP8 花屏兼容性。
  • ICE/TURN:香港自建 coturn,优先 UDP/3478,TCP/TLS 443 回退。
  • 端口:避免被省际 QoS 的高端口段牵连,范围收紧在 20000–40000 并监控。

/etc/turnserver.conf 关键项:

listening-port=3478
tls-listening-port=5349
fingerprint
lt-cred-mech
realm=edu.example.com
user=webrtc:StrongPassHere
no-sslv3
cipher-list="TLSv1.2+AESGCM"
no-tlsv1
no-tlsv1_1
min-port=20000
max-port=40000
no-udp-relay=no
# 多网卡发布
external-ip=203.0.113.2

6.2 HTTP/3 与回放缓存

Nginx(带 quiche 或官方 http3 版本均可):

http {
  sendfile on; tcp_nopush on; tcp_nodelay on;
  brotli on; brotli_comp_level 5;

  server {
    listen 443 ssl http2;
    listen 443 quic reuseport;  # HTTP/3
    ssl_certificate /etc/letsencrypt/live/edu/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/edu/privkey.pem;

    add_header Alt-Svc 'h3=":443"; ma=86400';
    add_header Strict-Transport-Security "max-age=63072000" always;

    location /hls/ {
      types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; }
      add_header Cache-Control "public, max-age=60";
      # 回源 Ceph/Nginx-OSS
      proxy_pass http://10.0.10.20;
    }
  }
}

经验:国内很多地区的 HTTP/3 表现优于 HTTP/2(特别是弱网与抖动场景),P95 抖动下 LL-HLS 的首帧明显快 200~400ms。

7. DNS 流量调度(不碰客户端也能见效)

  • 权威 DNS 开 Geo:cn.edu.example.com、sea.edu.example.com 分别指向不同 VIP/Anycast。
  • 健康检查:DNS 层每 10s 拉取我们 Prometheus 的 SLI(丢包、P95 RTT),触发流量挪移。
  • 最少变更原则:主域名 class.edu.example.com 做 CNAME 到区域域名,避免证书与浏览器缓存问题。

8. 监控与压测(落地)

  • 网络:Telegraf + Influx(端到端 RTT、丢包、抖动),MTR 定时任务对北/上/广/深/成/杭/武/西/昆 + SG/MY/TH/VN/ID/PH 打点。
  • 媒体:SFU 的每路 bitrate、nack/pli/fir、jitter buffer 指标入 Prometheus。
  • 压测:sipp(信令)、自研 WebRTC 机器人(Chrome headless)+ iperf3(回放与下载并发)。

示例:定时 MTR(片段):

#!/bin/bash
targets=( "101.6.6.6" "202.112.14.151" "61.91.8.1" "8.8.8.8" )
for t in "${targets[@]}"; do
  mtr -c 100 -w -o "LSD NBAW" "$t" > /var/log/net/mtr_$t_$(date +%F_%H%M).log
done

9. 部署中的“坑”与解法(现场记一笔)

  • UDP 被省级 QoS 限速:晚高峰部分省份 UDP 抖动飙升——临时把 TURN 的 TCP/TLS 回退权重抬高,WebRTC 牺牲一点延迟换稳定;峰值后再切回 UDP。
  • MTU 黑洞:某条上游给了 GRE,中间一段 1472 MTU,TLS 握手卡顿——全网关上加 MSS Clamping,问题立刻消失。
  • conntrack 爆表:开班季突增,nf_conntrack 直接顶到 2M——上调到 4M 并缩短 established 超时至 300s,配合 Nginx 与 SFU 的 keepalive 控制。
  • CMIN2 拥塞偶发:周三晚 SEA 峰值,VN/TH RTT 抬头——监控触发,把 SEA 的权威 DNS 15 分钟内偏向 PCCW,P95 直线回落。
  • BGP Flap 影响:有次上游维护没提前同步,BGP 抖动——我们在 FRR 开启 bgp dampening,并用 Keepalived 在 VIP 层做秒级漂移,避免连接“半开半关”。

10. 成本与带宽控制(95 分账单不肉疼)

  • 分层带宽:CN2 只走交互/白板与小流量回放;大文件/课件、非高实时回放尽量走 CU/CMI/PCCW。
  • 离线任务错峰:日志/录制上传压在夜间,避免冲击 95 分峰。
  • tc 整形:给非关键业务(如批量下载)加 HTB 限速,不跟互动抢“桶”。

tc 简单示意:

tc qdisc add dev eth0 root handle 1: htb default 20
tc class add dev eth0 parent 1: classid 1:1 htb rate 10gbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 7gbit ceil 10gbit   # 互动
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 3gbit ceil 10gbit   # 回放/下载

11. “前后对比”数据(真实量级,示例一周均值)

11.1 延迟与丢包(P95)

地区 调优前 RTT 调优后 RTT 丢包前 丢包后 主要策略
华北(电信) 110–150ms 55–70ms 3–5% <0.5% 入向 CN2、出向 CN2;MSS
华东(联通) 90–120ms 45–60ms 2–4% <0.5% 入向/出向 CU 优先
华南(移动) 80–100ms 40–55ms 2–3% <0.5% 入向/出向 CMI 优先
新加坡 35–45ms 20–28ms 1–2% <0.3% PCCW/CMI
马来西亚 45–65ms 25–40ms 1–2% <0.5% PCCW
泰国/越南 60–90ms 35–55ms 2–4% <0.8% PCCW/CMI 动态切换
印尼/菲律宾 80–110ms 50–80ms 3–6% ≈1% 峰值时偏 PCCW

11.2 并发容量

指标 调优前 调优后
单 SFU 最大稳定会话 ~600 1,200+
峰值回放带宽 12 Gbps 22–26 Gbps
峰值 CPU(SFU) 85–95% 60–70%(开 BBR、优化 IRQ/RPS)

12. 发布与回滚

蓝绿(VIP 切换):Keepalived + HAProxy,媒体节点先灰度 10%,无异常扩到 50% → 100%。

回滚按钮:一键恢复 DNS 权重、FRR 备份配置、iptables-restore 清单,严格 5 分钟内可回退。

13. 最小可执行清单(你照抄也能跑起来)

  • 上游:签好 BGP 多线(CN2/CMIN2/CU/PCCW),确认社区/本地偏好可控。
  • 内核:CentOS 7 装 ELRepo kernel 5.10,开启 BBR,sysctl 生效。
  • 网关:FRR 建邻,local-pref 定向;ipset + iptables mangle + ip rule 落地。
  • 媒体:WebRTC SFU + coturn,端口段收敛;Nginx 开 HTTP/3,回放缓存。
  • DNS:Geo 策略 + 健康检查;CNAME 主域名到区域域名。
  • 监控:MTR/丢包/RTT,Prometheus 抓 SFU 关键指标;告警触发 DNS 权重与路由策略联动。
  • 发布:蓝绿 + 回滚脚本;高峰前后各跑一次压测。

重构上线后的第一个周三晚自习,我在机房把羽绒服拉链拉到最上面,盯着大屏上 P95 RTT 的曲线稳稳贴在 60ms 下方。老师在直播里随手画了一个二次函数,十几座城市的孩子几乎同步“哦——”了一声。
那一刻我突然觉得,BGP 的那些数字、社区、路由图不再抽象,它们像一条条被打磨顺滑的路,把老师和学生连接在一起。你以为我们只是换了条线、调了个参数,其实我们是在把那几秒的不确定,换成了一堂课的确定。

如果你也准备在香港上 BGP 多线去服务国内与东南亚用户,上面这些手感和坑点,拿去就能用;有本地上游的社区表格或者更细的策略想法,也可以在此基础上继续深挖。祝你上线顺利,曲线漂亮。