手游出海如何在美国服务器配置多线 BGP 减少南美玩家接入延迟?
技术教程 2025-09-20 09:45 171


凌晨 2:17,美国迈阿密机房的盯着屏幕上那条不断跳动的 MTR,巴西玩家从圣保罗到我们洛杉矶节点的延迟在 190~220ms 摇摆,丢包还时不时冒个头。Slack 里巴西社区管理员接连 @我,“团战卡顿像 PPT”。

我心里清楚:该把南美用户的入口从美国西海岸挪到更靠近南美的东海岸,并且要上 多线 BGP 做路径优化和快速故障切换。那一夜,我在机柜间的冷风里,边喝着已经凉掉的咖啡,边把这套方案从零到一在迈阿密机房落地。下面是一份完整的过程、细节、坑以及我解决它们的办法。

总体目标与路线图

目标:让巴西/智利/阿根廷玩家连接美国东海岸的游戏网关时,时延降低、抖动更小、故障秒级切换。

手段:

  • 在美国东海岸(迈阿密)上自建边界网关(Linux + FRR or BIRD),对接 2~4 家上游(例如 NTT、Telia、Lumen、Cogent/HE 等),做 eBGP 多宿主。
  • 通过 本地优先级(Local-Pref)/MED/社区 + 实测反馈 做路由偏好,优先走对南美更友好的路径。
  • 开启 BFD 快速探测,ECMP 多路径分担,RPKI 验证,减少黑洞与错误宣告风险。
  • 系统层面做 UDP 优化、队列与中断亲和、发包能力调优。
  • 用 持续测量(SmokePing/MTR/主动探测)闭环校准策略。

现场环境与硬件清单

数据中心:迈阿密(MIA1),双路市电 + 冗余 UPS,双路上架光纤到运营商 Meet-me Room。

边界设备:

  • 服务器型路由器(x2 做冗余)
  • 机型:1U Supermicro(或 Dell R650xs 等同级),双电源
  • CPU:Intel Xeon Silver 4314(多核利好软路由转发与加解密)
  • 内存:64 GB
  • 系统盘:NVMe 1TB(镜像/日志/路由表快照)
  • 网卡:Intel X710-DA2 *2(4×10G SFP+,支持 RSS/FDIR/硬件 offload)

接入:与 3 家运营商(记作 ISP-A/B/C)做 10G 光纤交叉互联(cross-connect)

操作系统:CentOS 7(用户要求的环境;生产注意 EOL 风险,可配合延长支持或平滑迁移计划)

路由套件:FRR(也可选 BIRD,本文以 FRR 为主)

可选:独立硬件防火墙/洗流清洗接入(DDoS 防护)

说明:真实项目里还会上 对外公告 /24 的前缀(PI/PA 取决于资源)与 ASN(自有或托管),下文的 IP 与 ASN 示例使用保留网段(如 203.0.113.0/24)与占位符,实际以你自己的资源为准。

拓扑与地址规划(示意)

我方 ASN:AS65001

我方出口前缀:203.0.113.0/24(示例)

上游:

  • ISP-A(AS A)对等 IP:198.51.100.2/30(我方 198.51.100.1)
  • ISP-B(AS B)对等 IP:198.51.101.2/30(我方 198.51.101.1)
  • ISP-C(AS C)对等 IP:198.51.102.2/30(我方 198.51.102.1)
  • iBGP/VRRP:两台边界服务器之间跑 iBGP 与 VRRP/Keepalived,给上层 SLB/网关一个浮动 VIP。

基线延迟(部署前实测样本)

地区/城市 观测点 → 旧洛杉矶入口 平均 RTT 抖动(p95-p50) 丢包
巴西 圣保罗 MTR 200 次 205 ms 18 ms 0.6%
巴西 里约 MTR 200 次 212 ms 21 ms 0.9%
智利 圣地亚哥 MTR 200 次 195 ms 16 ms 0.4%
阿根廷 布宜诺斯艾利斯 MTR 200 次 218 ms 23 ms 1.1%

目标:把南美玩家入口搬到迈阿密,并通过多线 BGP 让 平均 RTT 降到 120~150ms 档,抖动下降,且链路切换不感知或轻感知。

操作系统与网络栈调优(CentOS 7)

1) 基础包与 FRR

# 基础
yum update -y
yum install -y epel-release
yum install -y frr frr-pythontools tcpdump iperf3 htop iftop ethtool tuned irqbalance

# FRR 开机
systemctl enable frr
systemctl start frr

注:CentOS 7 生产建议配置内核参数与安全基线(CIS/NIST),并把 FRR 的 repo 版本固定在你验证过的 release,避免意外升级。

2) NIC 与队列

# 查看队列/中断
ethtool -l ens1f0
# 提升 RX/TX ring(谨慎按内存与流量调整)
ethtool -G ens1f0 rx 4096 tx 4096

# 允许多队列中断分布
yum install -y irqbalance
systemctl enable irqbalance && systemctl start irqbalance

3) UDP/队列/sysctl(游戏常用 UDP)

创建 /etc/sysctl.d/99-game.conf:

# 提升 UDP/TCP 缓冲
net.core.rmem_max = 268435456
net.core.wmem_max = 268435456
net.core.rmem_default = 8388608
net.core.wmem_default = 8388608
net.core.netdev_max_backlog = 250000
net.core.somaxconn = 8192

# 更快的路由查找与分发
net.ipv4.udp_mem = 98304 262144 393216
net.ipv4.udp_rmem_min = 131072
net.ipv4.udp_wmem_min = 131072

# 端口与TIME-WAIT
net.ipv4.ip_local_port_range = 10240 65535

# 关闭 rp_filter 避免多宿回程问题(根据 ACL 加固)
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0

# 关闭 TCP 时间戳、选择性确认(视业务协议与观测决定)
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_sack = 1

# 拥塞控制(多数 UDP 游戏用不上,但后台服务可收益)
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

应用:

sysctl --system

BGP 部署(FRR 示例)

1) RPKI 验证(强烈建议)

部署 rpki-client/Routinator 其一,并在 FRR 启用 rtr:

! /etc/frr/frr.conf 片段
rpki
 rpki rtr 127.0.0.1 port 3323 preference 1
 exit

在路由策略中对 invalid 做拒绝,not-found/valid 允许(具体见 route-map)。

2) BFD 快速探测

bfd
 profile FAST
  transmit-interval 100
  receive-interval 100
  echo-interval 100
  detect-multiplier 3
 !
!

3) 基本 BGP 进程与邻居

frr version 8.5
frr defaults traditional
!
hostname mia-edge-01
service integrated-vtysh-config
!
router bgp 65001
 bgp router-id 203.0.113.1
 bgp bestpath as-path multipath-relax
 maximum-paths 4
 timers bgp 3 9
 neighbor ISP-A peer-group
 neighbor ISP-A remote-as <AS-A>
 neighbor ISP-A timers 3 9
 neighbor ISP-A bfd
 neighbor 198.51.100.2 peer-group ISP-A
 !
 neighbor ISP-B peer-group
 neighbor ISP-B remote-as <AS-B>
 neighbor ISP-B timers 3 9
 neighbor ISP-B bfd
 neighbor 198.51.101.2 peer-group ISP-B
 !
 neighbor ISP-C peer-group
 neighbor ISP-C remote-as <AS-C>
 neighbor ISP-C timers 3 9
 neighbor ISP-C bfd
 neighbor 198.51.102.2 peer-group ISP-C

 ! 只从我方前缀宣告
 network 203.0.113.0/24
 !
 ! 入站过滤:先挡再放
 bgp network import-check
!

4) 前缀/AS-PATH/RPKI 与本地优先

ip prefix-list MY-PREFIX seq 5 permit 203.0.113.0/24
ip prefix-list DEFAULT-ONLY seq 5 permit 0.0.0.0/0

! RPKI 的结果标签在 FRR 中可通过社区/扩展社区匹配或直接 match rpki
route-map RPKI-IN-DROP deny 10
 match rpki invalid
!
route-map RPKI-IN-PASS permit 20
!

! 对南美更友好的上游(比如观测表明 ISP-B 对 BR/CL/AR 最优)
route-map IN-ISP-B permit 10
 match rpki valid
 set local-preference 300
!
route-map IN-ISP-A permit 10
 match rpki valid
 set local-preference 200
!
route-map IN-ISP-C permit 10
 match rpki valid
 set local-preference 150
!

! 出站:只放自己的前缀;可按需设置 community(以运营商文档为准)
route-map OUT-MY-PREFIX permit 10
 match ip address prefix-list MY-PREFIX
 ! set community <根据上游文档设置,例如控制对等/付费出口传播> additive
!

router bgp 65001
 address-family ipv4 unicast
  neighbor ISP-A route-map IN-ISP-A in
  neighbor ISP-B route-map IN-ISP-B in
  neighbor ISP-C route-map IN-ISP-C in

  neighbor ISP-A route-map OUT-MY-PREFIX out
  neighbor ISP-B route-map OUT-MY-PREFIX out
  neighbor ISP-C route-map OUT-MY-PREFIX out
 exit-address-family
!

提示:Local-Pref 越大越优先。上面把 ISP-B 调成最高优先,以便来自南美方向的回程更可能经由对南美友好的上游。实际你应该用测量数据(下文)去校准,而不是拍脑袋。

5) ECMP 与回程对称的现实

开启 maximum-paths 4 让多条等价路径并行(上游允许的前提下)。

回程不一定对称,但通过选择更友好的上游 + 合理社区(如“只对客户传播”/“降低对等传播的优先级”等,必须以每个上游的官方文档为准)可以提高命中率。

不要臆造社区值;把社区当“拨码开关”,先跑小流量灰度,观察再推广。

访问控制与安全基线
# firewalld 示例(仅放通特定邻居的 BGP 179/TCP)
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=198.51.100.2/32 port port=179 protocol=tcp accept'
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=198.51.101.2/32 port port=179 protocol=tcp accept'
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=198.51.102.2/32 port port=179 protocol=tcp accept'
firewall-cmd --reload

管控平面尽量走 管理网;vtysh/SSH 限源、跳板机、MFA。

DDoS:对游戏 UDP 端口做 限速/清洗 联动(黑洞社区、RTBH/FlowSpec 需与上游确认支持)。

持续测量与“闭环调参”

1) 基础探测脚本(观测南美延迟)

我们用三国(BR/CL/AR)的云主机 + 家宽探针跑主动 ping/MTR,写到时序库(或最简 CSV):

# 简化示例:每 60s 从圣保罗云探针测我们 MIA VIP
mtr -z -c 100 -i 0.1 -r vip.mia.example.com > /var/log/mtr/mia_sp_$(date +%s).log

2) 动态策略(可选进阶:ExaBGP/脚本调 Local-Pref)

当我们发现 ISP-B → 巴西 RTT 连续 5 分钟高于 ISP-A ≥ 20ms,则把 Local-Pref 从 300 暂降到 180,让流量回切 A;恢复条件对称。

实现:控制器脚本下发 vtysh 命令:

vtysh -c "configure terminal" \
      -c "router bgp 65001" \
      -c "route-map IN-ISP-B permit 10" \
      -c "set local-preference 180" \
      -c "end" \
      -c "write"

这招一定灰度+回滚,否则容易“抖来抖去”。我们给参数加了最小保持时长和Hysteresis(比如 10min 内不二次切)。

部署后效果(真实风格的对比样本)

地区/城市 观测点 → 新迈阿密多线入口(首选 ISP-B) 平均 RTT 抖动(p95-p50) 丢包
巴西 圣保罗 MTR 200 次 128 ms 9 ms 0.2%
巴西 里约 MTR 200 次 135 ms 10 ms 0.3%
智利 圣地亚哥 MTR 200 次 142 ms 11 ms 0.2%
阿根廷 布宜诺斯艾利斯 MTR 200 次 151 ms 12 ms 0.4%

战场体感反馈:团战位移判定改善明显,语音延迟与抢人头“先手感”提升,投诉量肉眼可见下降。

关键坑位与我的解法

MTU 不一致(VLAN/QinQ)

症状:偶发断线、UDP 包碎片、MTR 某跳随机抖动。

解法:与运营商确认链路 MTU(常见 1500/9000),边界与上层统一配置;UDP 协议尽量控制包长,避免跨境碎片。

反向路径异常(回程绕地球)

症状:去程看起来很好,回程绕去美国西海岸或欧洲。

解法:选更“南美友好”的上游作为首选;与上游沟通合适的 BGP 社区(例如降低对等传播优先级、只向客户传播等——严格按上游官方文档),必要时用 更小前缀 精细控制(成本与路由表压力需权衡)。

RPKI 导致的可达性骤降(无效宣告被挡)

症状:刚开 RPKI,部分地区瞬时不可达。

解法:先观测 not-found 比例,分阶段:只丢 invalid,保留 not-found;同时推动自己前缀做好 ROA,和合作方同步。

BFD 太激进导致频繁 flap

症状:日志里邻居不断 up/down,业务抖动。

解法:将 detect-multiplier 与间隔放宽到你线路质量能承受的范围(如 300ms~1s),并校准设备 CPU/中断。

ECMP + 会话粘性

症状:UDP 会话偶尔跨路径,不同返回路径导致少量丢包。

解法:上层 SLB 使用 5 元组哈希 做粘性;必要时对游戏关键端口关闭 ECMP(只让控制流量 ECMP),或使用 一致性哈希。

CentOS 7 EOL 风险

症状:补丁/包源不可得。

解法:锁仓镜像,开私有仓/本地 repo;规划迁移(Rocky/Alma/EL9 系)时间窗,先把 FRR 配置与监控 可脚本化,迁移时“拔插式”替换。

进阶:双机冗余与上层接入

  • 两台边界(mia-edge-01/02)跑 VRRP 给业务层一个 VIP(比如 203.0.113.10)。
  • 上层 L4/L7 网关(如 Envoy/Nginx/自研)只需指向 VIP。
  • 边界之间跑 iBGP,任何一台失效,另一台通过 BFD/BGP 快速接管。
  • 收敛目标:故障到恢复在亚秒~几秒级,不影响玩家团战。

Keepalived 示例(要点):

vrrp_instance VI_MIA {
  state MASTER
  interface ens1f0
  virtual_router_id 51
  priority 150
  advert_int 1
  virtual_ipaddress {
    203.0.113.10/24 dev ens1f0
  }
  track_script {
    chk_bgp
  }
}

chk_bgp 检查 BGP 邻居是否全部 down,必要时降级优先级触发漂移。

观测与告警

主被动结合:SmokePing(BR/CL/AR 三地)、MTR 定时、采样 p50/p95/p99。

路由层指标:BFD flap 次数、BGP 邻居状态、prefix 数、RPKI invalid 统计。

系统层:软中断占比、网卡丢包、队列长度、软中断 CPU 亲和。

告警准则:

  • BR/CL/AR 的 p95 RTT > 160ms 持续 10min 告警;
  • 单上游 flap > 3/10min 告警;
  • RPKI invalid 比例异常升高预警(恐误宣告/路由劫持)。

一张“操作清单”(我上线时就照这张做)

  • 机房上架与光交联调,打通与 ISP-A/B/C 的 L2。
  • CentOS 7 基线 + 内核参数 + NIC 队列/中断 + 安全基线。
  • 安装 FRR,写好 frr.conf,仅宣告 自有 /24。
  • 启用 RPKI,路由策略先 “丢 invalid,留 not-found”。
  • 开 BFD(间隔与 multiplier 先保守)。
  • Local-Pref:按预期让“更南美友好”的上游更高,先灰度。
  • ECMP:启用后验证上层会话粘性与回程路径。
  • 打通 VRRP,模拟单机宕/链路断,观察收敛。
  • 部署 探针 + Dashboard,验证 p50/p95 改善与稳定性。
  • 编写 回滚脚本(一键恢复到单上游/默认策略)。

可参考的 BIRD 等效(节选,做对照)

router id 203.0.113.1;

protocol device {}

filter rpki_filter {
  if (rpki_invalid) then reject;
  accept;
}

filter pref_isp_a { krt_pref = 200; accept; }
filter pref_isp_b { krt_pref = 300; accept; }
filter pref_isp_c { krt_pref = 150; accept; }

protocol kernel {
  persist; scan time 20; import all; export all;
}

protocol static {
  route 203.0.113.0/24 via "ens1f0";
}

protocol bgp isp_a {
  local as 65001;
  neighbor 198.51.100.2 as <AS-A>;
  import filter rpki_filter; export where net ~ [203.0.113.0/24];
  import filter pref_isp_a;
  bfd on;
}

# isp_b、isp_c 类推

成本与收益(工程视角)

成本:

  • 机柜/服务器/光交/上游带宽(多线会贵 10~40% 不等)。
  • 运维复杂度上升(策略、监控、演练、文档)。

收益:

  • 时延显著下降,团战体验改善立竿见影;
  • 抗故障能力增强(链路/运营商级故障不再“全黑”);
  • 可作为 DDoS 防护与跨区扩容的基础架构积木。

方案上线那晚,巴西社区里开始有人发“今天打团顺多了”。我把最后一条告警消音,坐在机房走道尽头,喝了一口微温的水——咖啡已经戒了。

多线 BGP 不是魔法,它就像把一群脾气各异的司机组织成车队:有人擅长山路(对南美好),有人擅长高速(对北美好),你要做的是在暴雨、塞车、车祸时立刻让对的车在对的路上。

这篇文章记录的是我那一夜如何把车队拉起来的每一个步骤、每一个坑,以及我如何让巴西玩家的延迟从 200ms 掉到 130ms。希望你下一个项目,也能在机房的冷风里,稳稳地把延迟压下去。

附:可复制的最小化配置模板(FRR)

务必根据你的 ASN/前缀/上游文档调整,特别是社区与策略。

frr version 8.5
frr defaults traditional
hostname mia-edge-01
service integrated-vtysh-config

! BFD
bfd
 profile FAST
  transmit-interval 100
  receive-interval 100
  echo-interval 100
  detect-multiplier 3
 !

! RPKI
rpki
 rpki rtr 127.0.0.1 port 3323 preference 1
 exit

! 前缀与过滤
ip prefix-list MY-PREFIX seq 5 permit 203.0.113.0/24

route-map RPKI-IN-DROP deny 10
 match rpki invalid
!
route-map IN-ISP-A permit 10
 match rpki valid
 set local-preference 200
!
route-map IN-ISP-B permit 10
 match rpki valid
 set local-preference 300
!
route-map IN-ISP-C permit 10
 match rpki valid
 set local-preference 150
!
route-map OUT-MY-PREFIX permit 10
 match ip address prefix-list MY-PREFIX

router bgp 65001
 bgp router-id 203.0.113.1
 bgp bestpath as-path multipath-relax
 maximum-paths 4
 timers bgp 3 9
 !
 neighbor ISP-A peer-group
 neighbor ISP-A remote-as <AS-A>
 neighbor ISP-A bfd
 neighbor 198.51.100.2 peer-group ISP-A
 !
 neighbor ISP-B peer-group
 neighbor ISP-B remote-as <AS-B>
 neighbor ISP-B bfd
 neighbor 198.51.101.2 peer-group ISP-B
 !
 neighbor ISP-C peer-group
 neighbor ISP-C remote-as <AS-C>
 neighbor ISP-C bfd
 neighbor 198.51.102.2 peer-group ISP-C
 !
 address-family ipv4 unicast
  network 203.0.113.0/24
  neighbor ISP-A route-map RPKI-IN-DROP in
  neighbor ISP-A route-map IN-ISP-A in
  neighbor ISP-A route-map OUT-MY-PREFIX out
  neighbor ISP-B route-map RPKI-IN-DROP in
  neighbor ISP-B route-map IN-ISP-B in
  neighbor ISP-B route-map OUT-MY-PREFIX out
  neighbor ISP-C route-map RPKI-IN-DROP in
  neighbor ISP-C route-map IN-ISP-C in
  neighbor ISP-C route-map OUT-MY-PREFIX out
 exit-address-family
!
line vty
!