上一篇 下一篇 分享链接 返回 返回顶部

香港服务器结合大带宽与多线 BGP 分流,如何优化跨境直播带货高峰期的推流与回放?

发布人:Minchunlin 发布时间:2025-09-23 09:00 阅读量:968


618促销的前夜02:00。香港机房 18°C 的空调在头顶呼呼作响,机柜风扇像成排的小涡轮咆哮,交换机指示灯在黑暗里一明一灭。监控大屏上,OBS 的推流码率像心电图一样起伏,时不时刺出一根尖峰。去年的这个时刻,我们被跨境链路的抖动按在地上摩擦:丢包一度飙到 3%+,P95 RTT 破百,弹幕版面只剩一句话——“卡到爆”。那口气我咽不下去,直接在香港拉了一批 10G 大带宽机器,叠上多线 BGP,把推流与回放从逻辑到网络彻底拆开:SRT 顶上首跳,策略路由把大陆与海外分道而行,前端再用 CDN 扛住洪峰。一路踩坑、边修边跑,链路终于稳住了。这篇文章就是那次从零到一的完整复盘:思路、参数、配置、演练与回滚,全部摊开——你可以照着搭,今晚就能上。

场景与目标

业务场景:大陆主播在内地通过 OBS 推 RTMP/SRT 到香港,香港作为跨境首跳完成接入、转码、打包(HLS/LL-HLS/WebRTC)、再经内地 CDN 回源进行全国分发。

技术目标:

  • 推流稳定:跨境丢包 ≤ 0.5%,RTT 波动可控(P95 ≤ 80 ms)。
  • 回放低时延:移动端 HLS P95 起播 ≤ 1.2 s,卡顿率 ≤ 1.0%。
  • 弹性抗峰:单集群可承 20 万 QPS 的 .m3u8/.ts 请求,峰值 8–10 Gbps 可稳态输出。
  • 可观测与可回滚:出问题能 5 分钟内定位并灰度回滚。

1. 架构总览(接入分层 + 网络分流)

文字拓扑图(简化):

主播(OBS/SRT) --> [跨境] --> HK Ingest层(SRS集群)
                               |
                               +--> 转码/打包(FFmpeg/SRS HLS)
                               |
                               +--> 回放出口(Nginx/OpenResty + TLS + HTTP/2)
                                         |
                                         +--> 内地CDN(阿里/腾讯/百度等) <-- 终端用户

 

网络侧:香港机房接两条物理上行(线路 A=CN 优化/CTG/CN2,线路 B=国际混线/本地运营商),机房侧做 多线 BGP 智能入站;我在宿主 OS 上做 策略路由(PBR) 把“去往中国大陆段”的回源/回推走线路 A,海外/CDN/回源健康检查走线路 B,失效自动切换。

2. 选型与规格(我实际落地用的)

2.1 机型与网络

角色 机型 CPU 内存 磁盘 网卡 OS
Ingest x3 1U 双路 Intel Xeon Gold 6248R(24C*2) 128 GB NVMe 1.92TB *2 RAID1 2×10GbE(独立上联) CentOS 7
Transcode/Pack x2 2U AMD EPYC 7502P(32C) 256 GB NVMe 3.84TB *2 RAID1 2×25GbE(bond) CentOS 7
Edge/Origin x3 1U Intel Xeon 4216 128 GB NVMe 1.92TB *2 2×10GbE CentOS 7

交换机:ToR 万兆,支持 LACP;上行两条物理链路分别接 线路 A(CN 优化/CN2/CMI/CU专线) 与 线路 B(本地+国际)。

BGP:由机房/服务商提供多线 BGP(入站智能路由)。我不自带 ASN,出站我用策略路由做 PBR。

2.2 软件栈

  • SRS 5.x(RTMP/SRT/WebRTC 接入 + HLS/DVR/低延迟优化)
  • FFmpeg 6.x(转码切片)
  • OpenResty (Nginx 1.21+)(TLS、HTTP/2、缓存、鉴权)
  • Prometheus + Grafana(观测)
  • Keepalived + 健康检查脚本(线路失效检测与路由切换)
  • iptables/ipset + policy routing(目的地分流)

3. OS 基线与内核优化(CentOS 7)

CentOS 7 默认 3.10 内核,开启 BBR 要上新内核。我们用 ELRepo 的 mainline。

# 1) 基础工具
yum install -y epel-release yum-utils wget vim git htop jq net-tools chrony

# 2) 升级内核到 5.x(BBR 支持)
yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
yum --enablerepo=elrepo-kernel install -y kernel-ml

# 3) 设置默认引导为新内核
awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
grub2-set-default 0
reboot

重启后确认:

uname -r
# 5.x 内核

# 4) 开启 BBR + 基础 sysctl
cat >/etc/sysctl.d/99-tune.conf <<'EOF'
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.core.rmem_default = 67108864
net.core.wmem_default = 67108864
net.core.netdev_max_backlog = 250000
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
net.ipv4.tcp_congestion_control = bbr
net.ipv4.tcp_notsent_lowat = 16384
net.ipv4.tcp_mtu_probing = 1
net.ipv4.ip_local_port_range = 10000 65535
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
fs.file-max = 1048576
net.netfilter.nf_conntrack_max = 1048576
EOF

sysctl --system

# 5) ulimit
echo '* soft nofile 1048576' >> /etc/security/limits.conf
echo '* hard nofile 1048576' >> /etc/security/limits.conf

# 6) IRQ/NUMA 优化(示例)
yum install -y tuned
tuned-adm profile latency-performance

网卡队列优化(随机型):

ethtool -G eth0 rx 4096 tx 4096
ethtool -K eth0 gro on gso on tso on lro off

4. 多线分流:策略路由(PBR)+ 健康检查

4.1 基础思路

eth0 → 线路 A(CN 优化),eth1 → 线路 B(国际混线)

去往中国大陆网段(China IP 列表)标记为 fwmark=0x1 走 表 100(eth0)

其余目的地 走 表 200(eth1)

Keepalived 定时检测各自默认网关/对端探测 IP,失败则切主或降级到单线。

4.2 配置步骤

1)路由表定义

echo "100 cnline" >> /etc/iproute2/rt_tables
echo "200 intl"   >> /etc/iproute2/rt_tables

ip route add default via <GW_A> dev eth0 table cnline
ip route add default via <GW_B> dev eth1 table intl

# 基本优先规则
ip rule add fwmark 0x1 table cnline
ip rule add priority 100 from <eth0_ip>/32 table cnline
ip rule add priority 200 from <eth1_ip>/32 table intl

2)中国大陆 IP 集合(ipset)

实际生产我用离线打包的 China IP 列表(每日生成),示例脚本:

ipset create cn hash:net maxelem 131072

# 伪代码:把china_ip_list.txt逐行塞进ipset
while read -r cidr; do ipset add cn "$cidr"; done < /opt/china_ip_list.txt

3)mangle 标记 + PBR

# 标记去往中国大陆网段的流量
iptables -t mangle -A PREROUTING -m set --match-set cn dst -j MARK --set-mark 0x1
# 保持连接跟踪标记
iptables -t mangle -A PREROUTING -m mark --mark 0x1 -j CONNMARK --save-mark
iptables -t mangle -A OUTPUT     -m connmark --mark 0x1 -j MARK

4)Keepalived 健康检查(失效切换)

yum install -y keepalived

cat >/etc/keepalived/keepalived.conf <<'EOF'
vrrp_script chk_line_a {
  script "/usr/local/bin/check_gw.sh eth0 219.141.136.10"   # 电信DNS为例
  interval 3
  fall 3
  rise 2
}
vrrp_script chk_line_b {
  script "/usr/local/bin/check_gw.sh eth1 223.5.5.5"       # 阿里DNS为例
  interval 3
  fall 3
  rise 2
}

vrrp_instance ROUTE_HEALTH {
  state BACKUP
  interface eth0
  virtual_router_id 51
  priority 100
  advert_int 1
  track_script {
    chk_line_a
    chk_line_b
  }
  notify "/usr/local/bin/route_switch.sh"
}
EOF

check_gw.sh(简化):

#!/bin/bash
IF=$1; DST=$2
ping -I $IF -c2 -W1 $DST >/dev/null 2>&1
exit $?

route_switch.sh(根据脚本返回调整 ip route/ip rule,略)

注:rp_filter 必须调为 2(宽松),否则多宿多出口会被内核丢包。

5. 流媒体层:SRS + FFmpeg + Nginx(OpenResty)

5.1 安装 SRS(5.x)

# 依赖
yum install -y gcc gcc-c++ make openssl-devel zlib-devel
git clone https://github.com/ossrs/srs.git /opt/srs
cd /opt/srs/trunk
./configure && make -j$(nproc) && make install

5.2 SRS 核心配置(RTMP/SRT 接入 + HLS)

/usr/local/srs/conf/srs.conf(精简示例):

listen              1935;
max_connections     20000;
srs_log_tank        file;
srs_log_file        /var/log/srs.log;
daemon              on;

# 打开系统站点
vhost __defaultVhost__ {
    # 1) 推流接入
    ingest livestream {
        enabled     on;
    }

    # 2) SRT 接入(跨境抗抖更稳)
    srt_server {
        enabled     on;
        listen      10080;
        # SRT 建议参数
        latency             120
        peerlatency         60
        maxbw               20000000
        passphrase          your_srt_psk
        pbkeylen            16
    }

    # 3) HLS 打包
    hls {
        enabled         on;
        hls_fragment    2;
        hls_window      8;
        hls_path        /data/hls;
        hls_dispose     0;
        hls_td_ratio    1.5;
    }

    # 4) GOP 缓存 + 低延迟
    gop_cache       on;
    queue_length    30;

    # 5) 转码(调用 FFmpeg 生成多码率)
    transcode live2hls {
        enabled on;
        ffmpeg  /usr/bin/ffmpeg;
        engine abr720 {
            vcodec libx264; vprofile main; vpreset veryfast; vbitrate 3000;
            acodec aac; abitrate 128; asample_rate 44100; achannels 2;
            output rtmp://127.0.0.1/live/${app}?vhost=${vhost}/${name}_720p;
        }
        engine abr480 {
            vcodec libx264; vprofile main; vpreset veryfast; vbitrate 1800;
            acodec aac; abitrate 96; asample_rate 44100; achannels 2;
            output rtmp://127.0.0.1/live/${app}?vhost=${vhost}/${name}_480p;
        }
    }
}

要点:OBS 在主播端优先 SRT 推入(RTMP 备份)。SRT 的 ARQ/FEC 能显著降低跨境抖动带来的可见卡顿。

5.3 FFmpeg 手工转码示例(可替代/搭配 SRS 内置)

ffmpeg -re -i "rtmp://127.0.0.1/live/room001" \
  -c:v libx264 -preset veryfast -b:v 3000k -maxrate 3300k -bufsize 3000k -g 48 -keyint_min 48 -sc_threshold 0 \
  -c:a aac -b:a 128k -ar 44100 \
  -f hls -hls_time 2 -hls_list_size 4 -hls_flags delete_segments+program_date_time \
  -master_pl_name master.m3u8 \
  -hls_segment_filename "/data/hls/room001_720p_%04d.ts" \
  "/data/hls/room001_720p.m3u8"

5.4 Nginx/OpenResty 作为回放出口(TLS/HTTP2/鉴权)

安装(略),核心配置片段:

worker_processes auto;
worker_rlimit_nofile 1048576;

events { worker_connections 65535; }

http {
  sendfile on; tcp_nopush on; tcp_nodelay on;
  keepalive_timeout 65;
  aio on; directio 4m; output_buffers 16 512k;

  # HLS 缓存与范围请求
  proxy_buffering on;
  proxy_buffers 256 16k;
  proxy_busy_buffers_size 64m;
  proxy_read_timeout 10s;

  # 域名与证书
  server {
    listen 443 ssl http2;
    server_name live.example.hk;

    ssl_certificate     /etc/pki/tls/certs/live.crt;
    ssl_certificate_key /etc/pki/tls/private/live.key;

    # 简单 token 鉴权(示例,生产建议HMAC带时效)
    if ($arg_token = "") { return 403; }

    location /hls/ {
      types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; }
      add_header Cache-Control "max-age=2, public";
      add_header Access-Control-Allow-Origin *;
      root /data;
    }
  }
}

6. CDN 回源与边缘策略(内地用户加速)

我线上用的是“国内大型 CDN”,都支持 回源站点在香港 的场景。

域名:play.example.com CNAME 到 CDN

回源:https://live.example.hk/hls/(香港 Origin)

缓存规则:

.m3u8:缓存 2–5 秒(必须允许 Range/不缓存 301/302)

.ts:缓存 20–60 秒(视延迟与峰值权衡)

回源跟随跳转:开启

协议:边缘开启 HTTP/2,移动端优先 H2;部分 CDN 已支持 QUIC 可灰度开启

独立中国区:边缘节点仅在中国大陆,海外用户另设一个国际域名,走 线路 B 直出

源站限流:Nginx limit_conn/limit_req 防止回源风暴

7. 观测与告警

系统:node_exporter(CPU/Load/IRQ/软中断)、ethtool 统计

SRS:HTTP API 导出 ingest/clients/丢包/码率

Nginx:vhost 维度 2xx/4xx/5xx、TBT、上游时延

链路:到北京/上海/广州/成都/武汉/沈阳等 拨测点 RTT、丢包(mtr 自动汇总)

阈值告警(示例):

  • RTMP 推流 P95 丢包 > 0.8%(5 分钟)→ 严重
  • HLS 起播 P95 > 1.5s(10 分钟)→ 警告
  • 回源 5xx > 0.2%(1 分钟)→ 严重
  • 线路 A 健康检查失败 3 次 → 切到线路 B 并 @OnCall

8. 压测与标定

8.1 推流侧(主播模拟)

# SRT 模拟推流
srt-live-transmit file://sample.mp4 srt://live.example.hk:10080?streamid=publish/live/room001&latency=120

# RTMP 备份
ffmpeg -re -i sample.mp4 -c copy -f flv rtmp://live.example.hk/live/room001?token=abc123

8.2 回放侧(HLS 并发)

# m3u8 起播延迟/并发
ab -n 20000 -c 1000 https://play.example.com/hls/room001_720p.m3u8
# ts 文件压力
ab -n 200000 -c 4000 https://play.example.com/hls/room001_720p_0001.ts

9. 真实数据:优化前后对比(我线上观测的一组)

指标 优化前(去年) 优化后(今年)
跨境推流丢包(P95) 2.8% 0.4%
推流 RTT(P95) 120 ms 75 ms
起播时间(HLS,P95) 2.3 s 1.1 s
卡顿率(会话) 3.5% 0.8%
峰值回源带宽 6.1 Gbps 9.4 Gbps
回源 5xx(峰值 10 分钟) 0.6% 0.08%

其中 SRT 接入 + BBR + PBR(中国网段走线路 A) 是质变项;HLS 窗口下调到 2s*4 + CDN 边缘缓存细化,是量变项叠加。

10. 关键参数与建议(速查表)

类别 参数 建议值/说明
SRT latency 80–160 ms(跨境留冗余)
SRT maxbw 主播上行*1.5,限制突发
HLS hls_fragment 2 s
HLS hls_window 6–8 s
x264 gop 2s GOP(25/30/48 帧按帧率设)
Kernel tcp_congestion_control bbr
sysctl netdev_max_backlog 250000
Nginx worker_connections 65535+
CDN .m3u8 缓存 2–5s,注意 no-cache 灰度
路由 rp_filter 2(宽松)

11. 常见坑与现场处理

路由非对称 → RST/丢包
症状:RTMP/SRT 间歇性断流。
处理:rp_filter=2;确保回包沿着同一出口回去(本机源地址绑定 ip rule from)。如果上游 NAT,和机房沟通固定回程。

OBS 推流卡在 1–2 Mbps
症状:主播端上行被拥塞。
处理:SRT 替代 RTMP;主播侧也启用 BBR;避开晚高峰的 Wi-Fi,强制有线。

HLS 404/丢段
症状:客户端时钟不同步。
处理:所有节点启用 chrony 同步;hls_window 稍加大;CDN 允许负一段回源。

回源风暴
症状:边缘大量回源 .m3u8,源被压垮。
处理:Nginx 开 proxy_cache(如启用 OpenResty 可细化 TTL),.m3u8 2s,.ts 20–60s;限速/限并发。

NIC 软中断飙升
处理:ethtool -G 增队列、RPS/XPS,tuned-adm latency-performance,必要时绑核(/proc/irq/*/smp_affinity)。

TLS 握手开销
处理:开启 HTTP/2,合理 Keep-Alive,证书与 ECDSA 优先级;如 CDN 支持 QUIC 可灰度。

12. 上线步骤清单(我真正在机房走的顺序)

  • 裸金属装机 → RAID1 → CentOS 7 → 基础工具
  • ELRepo 升内核 → BBR → sysctl/ulimit → tuned
  • 配置网卡、静态路由、rp_filter
  • 部署 ipset+iptables mangle → ip rule/ip route
  • Keepalived 健康检查脚本 → 测试线路 A/B 断链切换
  • 编译/安装 SRS → 配 srs.conf → 本地回环推流联通
  • 部署 FFmpeg → 多码率转码 → 产出 HLS
  • 安装 OpenResty → TLS/HTTP2 → HLS 目录映射 → 鉴权
  • CDN 配置回源与缓存规则 → 观察边缘命中率
  • Prometheus/Grafana → 仪表盘与告警
  • 播放器端灰度(5%→20%→50%→100%)
  • 压测校验 → 峰值演练(伴随回滚预案)

13. 安全与合规要点

推流鉴权:URL 带时效 HMAC(exp+token),Nginx/OpenResty 校验 Lua 或 secure_link。

DDoS:选择自带清洗/高防的香港 BGP 资源;必要时在 CDN 层做黑洞/JS 挑战。

版权/资质:回放在内地落地分发涉及备案与内容合规,务必与法务确认 ICP/CDN/视听许可 相关事项。

14. 附:几段我在线上跑的配置片段(可直接抄)

14.1 systemd 服务(SRS)

# /etc/systemd/system/srs.service
[Unit]
Description=SRS Media Server
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/srs/objs/srs -c /usr/local/srs/conf/srs.conf
Restart=always
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

14.2 简易 HMAC 鉴权(OpenResty Lua 片段)

lua_shared_dict secrets 1m;

init_by_lua_block {
  secret = "your_hmac_secret"
}

set_by_lua_block $ok {
  local args = ngx.req.get_uri_args()
  local token = args.token or ""
  local exp = tonumber(args.exp or "0")
  if exp < ngx.time() then return "0" end
  local uri = ngx.var.uri
  local hmac = ngx.encode_base64(ngx.hmac_sha1(secret, uri..exp))
  if token == hmac then return "1" else return "0" end
}

if ($ok = "0") { return 403; }

14.3 China IP 列表每日更新(crontab)

# /etc/cron.d/update_cn_ip
5 4 * * * root /usr/local/bin/update_cn_ip.sh && systemctl reload nginx

update_cn_ip.sh 自行实现:下载/对比/原子替换 ipset。

618 当夜的第三场直播刚开场,我盯着 Grafana 的 SRT 丢包曲线从 0.7% 慢慢落到 0.3%,北京/武汉/成都拨测 RTT 稳在 60–80ms。CDN 命中率稳定在 97% 以上,客服频道竟然罕见地清净。运营同事发来一条消息:“这次不卡了,库存顶不住了。”
我笑了下,喝了口已经凉透的美式,把切换剧本从“灰度回滚”翻到“自动扩容”,又把大屏的背景颜色改成了绿色。
下一场马上开始,但我知道,这条跨境链路,已经站住了。

如果你的场景跟我类似——大陆推、香港首跳、内地分发,上面这一整套“大带宽 + 多线 BGP + PBR 分流 + SRT/BBR + HLS/CDN”的组合拳,基本就能稳住直播带货的高峰。

目录结构
全文