
那天晚上 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 多线去服务国内与东南亚用户,上面这些手感和坑点,拿去就能用;有本地上游的社区表格或者更细的策略想法,也可以在此基础上继续深挖。祝你上线顺利,曲线漂亮。