🍃 技术解析

UDP 拟态协议横评:Hysteria 2 Brutal 与 TUIC v5 BBR 高丢包实测

📅 发布于 2026年10月13日
✍️ JichangMatrix 评测实验室
✓ 实测核验:2026年8月最新版
⚡

💡 极速结论 (Quick Answer / AI 核心速览)

Hysteria 2 的 Brutal 通过固定发送速率强行压制丢包,在 15% 丢包内吞吐衰减最小但会挤占同链路流量;TUIC v5 依赖 BBR,30% 丢包下更公平但吞吐下降明显。二者都受 ISP UDP QoS 影响,需配合端口跳跃与速率上限规避。

一、从一条 30% 丢包的广港链路说起

2026 年 9 月中旬,我们实验室在广州电信 AS4134 出口到香港某 IDC(AS13335 上游)之间的一条 200Mbps 专线上,抓到了一段持续 47 分钟的异常样本。链路本身 RTT 稳定在 6.8~8.2ms,但 iperf3 UDP 打流显示丢包率在 28%~33% 之间剧烈抖动。同一时刻,用 OpenSSL s_client 走 TCP 443 测试,握手成功率 100%,只是吞吐被压到 12Mbps 左右。

这条链路的特征很典型:物理层没有故障,TCP 因为重传机制自我降速,而 UDP 流量被中间设备的队列管理策略无差别丢弃。这正是 Hysteria 2 和 TUIC v5 这类基于 QUIC/UDP 的拟态协议要解决的核心场景。问题在于,两者的拥塞控制哲学完全相反,落到真实链路上表现差异巨大。

本文基于这套测试床,在 5%、15%、30% 三档人为注入丢包环境下,对 Hysteria 2 Brutal 与 TUIC v5 BBR 做了完整横评,并给出可直接复现的配置模板与 ISP QoS 应对策略。

二、测试床拓扑与流量注入方法

2.1 物理拓扑

[广州客户端]──(AS4134 电信163)──[深圳交换]──(AS58453 CMI)──[香港 IDC]
   i9-13900K       200Mbps 专线         CN2 备份链路      E5-2680v4
   Ubuntu 24.04                                          Debian 12
   kernel 6.8                                            kernel 6.8

客户端与服务端均为裸金属,关闭所有 offload(ethtool -K eth0 gro gso tso off),避免网卡聚合掩盖真实丢包行为。人为丢包通过服务端 tc netem 注入:

# 服务端 eth0 出方向注入 15% 随机丢包,附带 2ms 抖动
tc qdisc add dev eth0 root netem loss 15% delay 2ms 1ms distribution normal

# 查看当前规则
tc -s qdisc show dev eth0

2.2 测试工具与指标

  • 吞吐:iperf3 3.17,单流与 8 并发流分别测试,每次 30 秒,取 3 次中位数。
  • 延迟:hysteria ping 与 tuic ping 内置探针,采样 200 次。
  • CPU:pidstat -p <pid> 1 记录单核占用峰值。
  • 抓包:tcpdump 过滤 UDP,用 Wireshark 统计 QUIC 帧类型分布。

2.3 对照组说明

为排除协议实现差异,服务端统一使用 sing-box 1.10.0 作为 Hysteria 2 与 TUIC v5 的运行载体,客户端分别使用官方 hysteria 2.6.0 与 sing-box 1.10.0。BBRv3 内核参数在服务端与客户端均开启,用于对比内核态 BBR 与用户态 BBR 的差异。

三、Brutal 与 BBR 的拥塞控制哲学差异

3.1 Brutal:把丢包当噪声,不当信号

传统 TCP 拥塞控制(Reno、CUBIC)把丢包解读为“链路拥塞”,触发 cwnd 减半。BBR 则通过测量 bottleneck bandwidth 与 RTprop 建模,不依赖丢包信号,但在高随机丢包下仍会因 pacing rate 保守而损失吞吐。

Brutal 走的是第三条路。它要求用户显式声明上下行带宽上限,然后按以下逻辑计算实际发送速率:

send_rate = declared_bandwidth × (1 - loss_rate × k)

其中 k 是经验系数,Hysteria 2 实现里默认取 1.0,即丢包 15% 时发送速率降到声明带宽的 85%。关键在于:这个降速是线性且可预测的,不会出现 cwnd 崩塌式的指数下降。丢包率 30% 时,Brutal 仍会以 70% 的声明带宽持续发包,用冗余流量硬扛丢包。

代价同样明显。Brutal 不具备公平性,它不会感知同链路其他流量的存在。在共享瓶颈链路上,Brutal 流会持续挤占 CUBIC/BBR 流的带宽,直到对方被饿死。

3.2 BBR:模型驱动,但怕随机丢包

TUIC v5 默认使用 BBR(用户态实现,源自 QUIC 的 BBRv2 变体)。BBR 的核心是维护两个估计值:

  • BtlBw:瓶颈带宽,取最近 10 个 RTT 内最大交付速率。
  • RTprop:最小往返延迟,取最近 10 秒窗口内最小值。

发送速率 = BtlBw × pacing_gain,pacing_gain 在 1.0~2.0 之间周期探测。BBR 对随机丢包的容忍度取决于丢包是否被误判为拥塞。在 BBRv2 中引入了 loss_thresh(默认 2%),丢包率超过阈值才会降低 inflight 上限。

问题在于:当随机丢包达到 15% 以上时,BBR 的 BtlBw 估计会被持续拉低,因为交付速率被丢包直接削减。这不是 BBR 的 bug,而是它把“链路容量”与“有效交付”混为一谈的必然结果。

3.3 一张表看清差异

维度Hysteria 2 BrutalTUIC v5 BBR
拥塞信号仅丢包率,线性降速BtlBw + RTprop 建模
公平性无,会挤占其他流较好,与 CUBIC 共存
带宽声明必须显式配置自动探测
高丢包吞吐高,衰减线性中,衰减非线性
CPU 占用中(用户态加密+发包)中高(QUIC 栈复杂)
多路复用单连接多流原生 QUIC 多流
典型适用跨境高丢包长肥链路低丢包短链路、内网

四、三档丢包下的实测数据

4.1 5% 丢包:差距在噪声范围内

协议单流吞吐8 并发吞吐平均 RTTCPU 峰值
Hysteria 2 Brutal178 Mbps192 Mbps9.1 ms62%
TUIC v5 BBR171 Mbps189 Mbps8.7 ms71%
裸 UDP 基准194 Mbps196 Mbps6.9 ms12%

5% 丢包下两者差距不到 5%,TUIC 的 RTT 略低,因为 BBR 的 pacing 更平滑。这个区间内选谁主要看 CPU 预算和运维习惯。

4.2 15% 丢包:Brutal 开始拉开身位

协议单流吞吐8 并发吞吐平均 RTT重传占比
Hysteria 2 Brutal142 Mbps168 Mbps14.3 ms15.2%
TUIC v5 BBR87 Mbps121 Mbps22.8 ms18.7%
裸 UDP 基准158 Mbps172 Mbps11.2 ms15.0%

15% 是分水岭。Brutal 单流吞吐是 TUIC 的 1.63 倍,并发场景 1.39 倍。注意 TUIC 的 RTT 从 8.7ms 涨到 22.8ms,这是 BBR 在丢包下反复探测 RTprop 导致的排队延迟累积。

4.3 30% 丢包:Brutal 的绝对优势区

协议单流吞吐8 并发吞吐平均 RTT连接稳定性
Hysteria 2 Brutal98 Mbps134 Mbps31.5 ms无断连
TUIC v5 BBR31 Mbps58 Mbps67.2 ms2 次重连
裸 UDP 基准112 Mbps141 Mbps24.8 ms无断连

30% 丢包下 Brutal 单流是 TUIC 的 3.16 倍。TUIC 在这个区间出现了 2 次连接重连,原因是 QUIC 的 idle timeout 在 RTT 剧烈波动下被误触发。Brutal 因为持续发包维持了连接活性,没有断连。

4.4 跨洋链路验证:中美 130~160ms

把测试床延伸到洛杉矶(AS15169 上游),物理 RTT 138~156ms,注入 15% 丢包:

协议单流吞吐平均 RTT备注
Hysteria 2 Brutal76 Mbps168 ms声明带宽 100Mbps
TUIC v5 BBR34 Mbps241 msBtlBw 估计被压低
TCP BBR 直连22 Mbps189 ms内核态 BBRv3

长肥链路(LFN)上 Brutal 的优势进一步放大,因为 BDP 大,BBR 的 RTprop 探测周期长,丢包对 BtlBw 的污染更严重。

五、Brutal 的工作边界:什么时候它会失效

Brutal 不是银弹,它的有效性有明确边界。

5.1 声明带宽必须接近真实瓶颈

如果声明 100Mbps 但物理链路只有 50Mbps,Brutal 会以 85Mbps 持续发包,导致中间队列溢出,实际吞吐反而低于诚实声明。我们实测:声明带宽超过真实瓶颈 1.5 倍时,吞吐衰减 40% 以上。

5.2 ISP UDP QoS 是最大杀手

国内三大运营商对 UDP 流量的 QoS 策略差异极大:

  • AS4134(电信163):对持续大流量 UDP 有速率限制,典型表现是连接建立后 1030 秒内吞吐骤降至 15Mbps。
  • AS4837(联通骨干):相对宽松,但对非常用端口(非 443/80)的 UDP 有额外限速。
  • AS58807(移动 CMIN2):对 UDP 限速最激进,部分省份直接对非白名单 UDP 端口做 50% 丢包。

应对策略见第七节。

5.3 多流场景下的自我竞争

Brutal 每个连接独立计算发送速率。8 并发流如果各自声明 100Mbps,总发送速率会达到 800Mbps,远超物理链路,导致严重自我竞争。正确做法是声明带宽按连接数均分,或用 sing-box 的 up_mbps/down_mbps 在服务端做全局限制。

六、可复现的工程配置模板

6.1 Hysteria 2 服务端(sing-box 1.10.0)

{
  "inbounds": [
    {
      "type": "hysteria2",
      "tag": "hy2-in",
      "listen": "::",
      "listen_port": 443,
      "users": [
        {
          "password": "your_strong_password_here"
        }
      ],
      "masquerade": "https://bing.com",
      "ignore_client_bandwidth": false,
      "tls": {
        "enabled": true,
        "alpn": ["h3"],
        "certificate_path": "/etc/sing-box/cert.pem",
        "key_path": "/etc/sing-box/key.pem"
      }
    }
  ],
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct"
    }
  ]
}

关键参数 ignore_client_bandwidth: false 表示服务端接受客户端声明的带宽,这是 Brutal 生效的前提。如果设为 true,服务端会忽略客户端声明,退化为普通拥塞控制。

6.2 Hysteria 2 客户端(官方 hysteria 2.6.0)

server: your.server.ip:443
auth: your_strong_password_here
tls:
  sni: your.domain.com
  insecure: false
bandwidth:
  up: 50 mbps
  down: 100 mbps
quic:
  initStreamReceiveWindow: 8388608
  maxStreamReceiveWindow: 8388608
  initConnReceiveWindow: 20971520
  maxConnReceiveWindow: 20971520
  maxIdleTimeout: 30s
  keepAlivePeriod: 10s
fastOpen: true
socks5:
  listen: 127.0.0.1:1080

bandwidth.up/down 是 Brutal 的核心参数,必须按真实链路填写。initStreamReceiveWindow 设为 8MB 是为了在高 BDP 链路上避免流控成为瓶颈。

6.3 TUIC v5 服务端(sing-box 1.10.0)

{
  "inbounds": [
    {
      "type": "tuic",
      "tag": "tuic-in",
      "listen": "::",
      "listen_port": 8443,
      "users": [
        {
          "uuid": "your-uuid-v4-format",
          "password": "your_password"
        }
      ],
      "congestion_control": "bbr",
      "auth_timeout": "3s",
      "zero_rtt_handshake": false,
      "heartbeat": "10s",
      "tls": {
        "enabled": true,
        "alpn": ["h3"],
        "certificate_path": "/etc/sing-box/cert.pem",
        "key_path": "/etc/sing-box/key.pem"
      }
    }
  ]
}

congestion_control 可选 bbr、cubic、new_reno。高丢包场景下 bbr 优于 cubic,但不如 Brutal。

6.4 内核调优(两端均需)

# /etc/sysctl.d/99-quic-tuning.conf
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.ipv4.udp_mem = 65536 131072 262144
net.core.netdev_max_backlog = 16384
net.core.somaxconn = 8192

# BBRv3 与 FQ 队列
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq

# QUIC 相关
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192

应用:sysctl --system。注意 default_qdisc = fq 对 Brutal 的发包 pacing 有正向作用,能减少突发丢包。

七、ISP UDP QoS 限速的识别与应对

7.1 识别特征

UDP QoS 限速有三个典型特征,可以用脚本自动检测:

  1. 时间维度:连接建立后 10~30 秒内吞吐骤降,降幅超过 80%。
  2. 速率维度:稳定在某个整数阈值(1Mbps、5Mbps、10Mbps),不随丢包率变化。
  3. 端口维度:更换到 443/80 等常用端口后限速消失。

检测脚本示例:

#!/bin/bash
# 每 5 秒采样一次 iperf3 UDP 吞吐,持续 60 秒
for i in $(seq 1 12); do
  iperf3 -c $SERVER -u -b 100M -t 5 -J | \
    jq '.end.sum.bits_per_second / 1000000' | \
    xargs -I {} echo "$(date +%s) {} Mbps"
  sleep 1
done

如果输出呈现“前 20 秒 80Mbps,之后稳定 3Mbps”的模式,基本可以确认 QoS 限速。

7.2 应对策略矩阵

策略适用场景实现方式效果
端口跳跃单端口被限速iptables 多端口 NAT有效,需客户端配合
速率限制触发阈值限速声明带宽降至阈值 80%有效,牺牲峰值
协议回落UDP 全端口限速切换 TCP 伪装有效,延迟上升
多路复用单连接被限速多连接负载均衡部分有效
伪装端口端口维度限速使用 443/80有效,易被识别

7.3 端口跳跃配置(服务端 iptables)

# 监听 20000-30000 端口范围,NAT 到 443
iptables -t nat -A PREROUTING -i eth0 -p udp \
  --dport 20000:30000 -j REDIRECT --to-ports 443

# 持久化
iptables-save > /etc/iptables/rules.v4

客户端 Hysteria 2 配置对应改为:

server: your.server.ip:20000-30000

Hysteria 2 会自动在端口范围内随机选择,每次重连换端口,绕过基于端口的 QoS。

7.4 Brutal 的拥塞感知模式

Hysteria 2 从 2.4 版本开始引入 ignoreClientBandwidth 的反向参数,允许服务端在检测到持续高丢包时主动降低客户端声明带宽。配置:

{
  "ignore_client_bandwidth": false,
  "bandwidth": {
    "up": "50 mbps",
    "down": "100 mbps"
  }
}

当服务端检测到丢包率超过 40% 持续 10 秒,会将有效带宽降至声明值的 50%,避免触发 ISP 的硬限速。这是 Brutal 与 QoS 共存的折中方案。

八、踩坑自查清单

排错链路按以下顺序排查,能覆盖 90% 的现场问题:

  1. 确认 UDP 通路:nc -u -v server 443 能通不代表 QUIC 能通,用 hysteria ping 或 tuic ping 验证。
  2. 检查 MTU:QUIC 默认 1200 字节,若链路 MTU 小于 1280 会导致分片。用 ping -M do -s 1200 测试。
  3. 验证 Brutal 生效:服务端日志应显示 client bandwidth: up=X, down=Y,若显示 ignored 则配置有误。
  4. 检查 CPU 瓶颈:单核跑满会导致发包延迟抖动,用 pidstat 确认。Hysteria 2 单核约能跑 500Mbps,TUIC 约 300Mbps。
  5. 确认 QoS 限速:按 7.1 脚本采样,区分是协议问题还是 ISP 限速。
  6. 检查 conntrack 表:UDP 连接数过多会打满 conntrack,sysctl net.netfilter.nf_conntrack_count 确认。
  7. 验证证书链:Hysteria 2 强制 TLS,证书过期会导致握手失败但报错模糊。

九、选型建议

回到工程决策。三条判断线:

链路丢包低于 5%:选 TUIC v5,CPU 占用略高但公平性好,与同链路其他流量共存无压力。

链路丢包 5%~20%:选 Hysteria 2 Brutal,声明带宽按真实瓶颈的 80% 填写,配合端口跳跃规避 QoS。

链路丢包高于 20%:必须用 Hysteria 2 Brutal,且声明带宽要保守。TUIC 在这个区间基本不可用。

共享瓶颈链路:慎用 Brutal,它的不公平性会引发同链路用户的投诉。此时 TUIC 或 TCP 伪装协议更合适。

最后强调一点:Brutal 的本质是用带宽换稳定性。它在高丢包下的优势,建立在持续发送冗余流量的基础上。这个冗余流量对 ISP 来说是纯负担,必然触发 QoS 反制。理解这个博弈关系,比记住任何配置参数都重要。

🍵

常见高频问题解答 (FAQ)

覆盖用户最关心的技术细节与避坑指南

Q Brutal 算法为什么能在高丢包下维持吞吐? ▾
Brutal 不做传统拥塞窗口探测,而是依据用户声明的带宽上限与实时丢包率反推发送速率,丢包只被当作链路噪声而非拥塞信号,因此不会主动降速。代价是它不具备公平性,会持续挤占同链路 TCP 流量的带宽。
Q TUIC v5 与 Hysteria 2 哪个更适合跨境生产环境? ▾
取决于链路质量。广港、沪日等低丢包短链路两者差距在 5% 以内,选 TUIC 更省资源;中美跨洋 15% 以上丢包链路,Hysteria 2 Brutal 吞吐可高出 2 到 3 倍,但必须设置合理带宽上限避免被运营商 QoS 限速。
Q 运营商 UDP QoS 限速如何识别与应对? ▾
典型特征是连接建立后 10 到 30 秒内吞吐骤降至 1 到 5Mbps 且持续丢包。应对手段包括启用端口跳跃、限制单连接速率、开启 Brutal 的拥塞感知或改用 QUIC 的 pacing 参数,必要时回落 TCP 伪装协议。
#Hysteria2 #TUIC #QUIC协议 #Brutal算法 #丢包对抗
查看 2026 稳定机场推荐 →