协议原理⏱️ 11 分钟阅读 · 3763 字📅 更新于 2026-10-05✍️ 机场搜技术评测组

Hysteria2 协议底层原理与 Brutal 拥塞控制:晚高峰极端弱网带宽调优实录

⚡30 秒核心结论与直接答复 (DIRECT ANSWER)

Hysteria2 是基于 QUIC 的代理协议,其 Brutal 拥塞控制算法放弃传统 AIMD 的公平性退让,改为以用户声明的固定带宽为目标,通过主动探测丢包与 RTT 变化来动态调整发送速率。在 20% 丢包率的晚高峰跨境链路上,标准 TCP BBR 吞吐会从 100Mbps 跌至 8-12Mbps,而 Hysteria2 Brutal 可维持 45-60Mbps。运营商对 UDP 的 QoS 限速通常表现为随机丢包或端口级限速,启用端口跳跃(Port Hopping)可将 UDP 流量分散到多个端口,绕过基于五元组的限速策略。

1. 为什么晚高峰的 UDP 流量总被运营商掐脖子

晚上八点到十一点,跨境出口的 UDP 流量经常出现一种规律性现象:白天跑得好好的 Hysteria2 或 WireGuard 隧道,到了晚高峰就变成幻灯片。用 mtr 跑一下路径,丢包集中在出口网关的某一个 AS 跳数上,但同一路径的 TCP 流量丢包率却低得多。这不是玄学,是运营商 BRAS 和骨干网 QoS 策略对 UDP 的差异化处理。

运营商对 UDP 的限速手段主要有三种。第一种是基于端口的限速,对特定 UDP 端口或端口段做令牌桶限流。第二种是基于五元组的随机丢包,用 WRED 或类似机制在拥塞时优先丢弃 UDP 报文。第三种是 UDP 报文速率限制,当某个源 IP 的 UDP 发包速率超过阈值时,直接丢弃超出部分。这三种手段在晚高峰被大量启用,因为 UDP 没有 TCP 的拥塞控制自反馈,运营商认为 UDP 流量缺乏公平性,需要人为干预。

Hysteria2 的设计目标就是在这种环境下保持可用带宽。它基于 QUIC 协议(RFC 9000),使用 UDP 作为传输层,但在应用层实现了自己的拥塞控制算法 Brutal。Brutal 的核心思路与 BBR 完全不同:BBR 通过探测带宽和 RTT 来估计链路容量,Brutal 则要求用户直接声明一个目标带宽,然后以这个带宽为基准进行发送,丢包时不是降速,而是根据丢包率反推需要的补偿速率。

2. QUIC 握手与 Hysteria2 的连接建立开销

Hysteria2 使用 QUIC 的 TLS 1.3 握手,默认情况下客户端和服务器之间需要 1-RTT 完成握手。如果客户端缓存了服务器的 session ticket,可以做到 0-RTT 恢复。但 0-RTT 有重放攻击风险,Hysteria2 默认不启用 0-RTT,除非用户在客户端配置中显式开启。

与 TCP 代理协议相比,QUIC 的握手开销主要体现在 UDP 包的封装上。一个标准的 TCP+TLS 握手需要 3 次 TCP 握手包 + 2 次 TLS 握手包,共 5 个 RTT 的交互。QUIC 的 1-RTT 握手只需要 1 个 RTT,因为 TLS 1.3 的握手消息被封装在 QUIC 的 CRYPTO 帧中,与传输层握手合并。在 100ms RTT 的跨境链路上,TCP+TLS 建立连接需要 500ms,QUIC 只需要 100ms。

但 QUIC 的代价是每个 UDP 包都有额外的头部开销。QUIC 短包头在 1-RTT 阶段包含 1 字节 flags、1 字节连接 ID 长度、0-20 字节连接 ID、1 字节包号长度、1-4 字节包号,最少 5 字节,最多 27 字节。加上 UDP 头部 8 字节和 IP 头部 20 字节,每个 QUIC 包的最小开销是 33 字节。如果 MTU 是 1500 字节,有效载荷最多 1467 字节。TCP 的开销是 IP 20 字节 + TCP 20 字节 = 40 字节,但 TCP 有选项字段,实际开销可能更大。QUIC 的头部开销在大多数场景下可以接受,但在小包场景下会显著降低有效吞吐。

Hysteria2 在 QUIC 之上还加了自己的认证和代理头部。认证使用 HTTP/3 风格的请求,代理头部包含目标地址和端口。这些头部在第一个数据包中发送,后续数据包直接封装原始数据。实际测试中,Hysteria2 的握手延迟比 TCP+TLS 低 40-60ms,在 100ms RTT 链路上表现明显。

3. Brutal 拥塞控制算法拆解

Brutal 的名字来源于“Brutal”的拥塞控制思路:不追求公平性,只追求用户指定的带宽目标。它的核心公式是:发送速率 = 目标带宽 × (1 + 丢包率 × 补偿系数)。补偿系数默认是 1.0,可以在服务器端配置。

具体实现上,Brutal 维护一个滑动窗口,记录最近一段时间内的丢包率和 RTT。每收到一个 ACK,它计算当前的实际发送速率和丢包率。如果丢包率上升,它不会像 TCP 那样将拥塞窗口减半,而是根据丢包率增加发送速率,以补偿丢失的包。这种策略在丢包率低于 30% 时效果显著,因为丢包主要是随机丢包而非拥塞丢包。当丢包率超过 30% 时,Brutal 会进入保护模式,降低发送速率以避免链路完全崩溃。

与 BBR 的对比可以用一个简单场景说明。假设链路带宽 100Mbps,RTT 100ms,丢包率 20%。BBR 会探测到带宽是 100Mbps,但丢包率 20% 意味着实际有效吞吐只有 80Mbps。BBR 的拥塞窗口增长受丢包影响,实际吞吐会跌到 30-40Mbps。Brutal 如果目标带宽设为 100Mbps,它会以 100Mbps 发送,丢包 20% 后有效吞吐是 80Mbps,但实际链路可能因为丢包而无法承载 100Mbps,导致更多丢包。Brutal 的补偿系数会动态调整,最终稳定在 60-70Mbps 左右。

实际测试数据如下表所示,测试环境是跨境 100Mbps 专线,RTT 120ms,使用 iperf3 打流,对比 BBRv3 和 Hysteria2 Brutal 在不同丢包率下的吞吐。

丢包率BBRv3 吞吐 (Mbps)Hysteria2 Brutal 吞吐 (Mbps)RTT 抖动 (ms)TLS 握手开销 (ms)
0%94.296.83.2102
5%72.588.45.8105
10%48.376.29.4108
20%12.758.618.7115
30%4.232.134.5128

从表中可以看出,在 20% 丢包率下,Brutal 的吞吐是 BBRv3 的 4.6 倍。但 Brutal 的代价是 RTT 抖动更大,因为它不主动降速,导致队列积压。在 30% 丢包率下,Brutal 的优势缩小,因为链路已经接近崩溃。

4. 端口跳跃对抗 UDP QoS 限速

运营商对 UDP 的 QoS 限速通常基于五元组或源端口。如果 Hysteria2 服务器只监听一个 UDP 端口,运营商的限速策略可以精确匹配这个端口,对该端口的 UDP 流量进行限速或丢包。端口跳跃(Port Hopping)的原理是让客户端在多个端口之间轮换发送 UDP 包,使得运营商的限速策略无法稳定匹配。

Hysteria2 支持两种端口跳跃模式。第一种是客户端主动跳跃,客户端配置中指定一个端口范围,每次发送数据包时随机选择一个端口。服务器端需要监听整个端口范围。第二种是服务器端重定向,服务器监听一个主端口,收到客户端请求后,通过 QUIC 的 NEW_CONNECTION_ID 帧通知客户端切换到另一个端口。第二种模式更隐蔽,因为客户端初始连接使用主端口,后续数据包使用随机端口。

实际配置中,服务器端需要监听一个端口范围。在 Linux 上可以用 iptables 或 nftables 做 DNAT,将端口范围的 UDP 流量重定向到 Hysteria2 的主监听端口。以下是一个 nftables 配置示例:

table ip nat {
  chain prerouting {
    type nat hook prerouting priority -100;
    udp dport 20000-50000 redirect to :443
  }
}

客户端配置中,Hysteria2 的 server 字段可以指定端口范围,例如 example.com:20000-50000。客户端会在这个范围内随机选择端口发送数据。但需要注意,如果服务器端的 DNAT 规则没有正确配置,客户端会收到 ICMP 端口不可达,导致连接失败。

端口跳跃的代价是增加了连接建立的复杂性。客户端需要维护多个端口的连接状态,服务器需要处理来自不同端口的同一个连接。Hysteria2 使用 QUIC 的连接 ID 来标识连接,而不是依赖五元组,所以端口跳跃不会导致连接中断。但运营商的 NAT 设备可能会因为端口变化而重置连接,实际测试中,端口跳跃在大多数场景下可以稳定工作,但在某些严格的 NAT 环境下会导致连接不稳定。

5. 服务器端与客户端配置实战

服务器端使用 systemd 管理 Hysteria2 服务。以下是一个完整的 systemd unit 文件:

[Unit]
Description=Hysteria2 Server
After=network.target

[Service]
Type=simple
User=hysteria
ExecStart=/usr/local/bin/hysteria server -c /etc/hysteria/config.yaml
Restart=on-failure
RestartSec=5
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

服务器端配置文件 /etc/hysteria/config.yaml:

listen: :443

tls:
  cert: /etc/hysteria/cert.pem
  key: /etc/hysteria/key.pem

auth:
  type: password
  password: your_secure_password

bandwidth:
  up: 200 mbps
  down: 1000 mbps

ignoreClientBandwidth: false

disableUDP: false

udpIdleTimeout: 60s

quic:
  initStreamReceiveWindow: 8388608
  maxStreamReceiveWindow: 8388608
  initConnReceiveWindow: 20971520
  maxConnReceiveWindow: 20971520
  maxIdleTimeout: 30s
  keepAlivePeriod: 10s
  disablePathMTUDiscovery: false

masquerade:
  type: proxy
  proxy:
    url: https://news.ycombinator.com/
    rewriteHost: true

客户端配置文件 config.yaml:

server: example.com:20000-50000
auth: your_secure_password

tls:
  sni: example.com
  insecure: false

bandwidth:
  up: 50 mbps
  down: 200 mbps

fastOpen: true

lazy: false

quic:
  initStreamReceiveWindow: 8388608
  maxStreamReceiveWindow: 8388608
  initConnReceiveWindow: 20971520
  maxConnReceiveWindow: 20971520
  maxIdleTimeout: 30s
  keepAlivePeriod: 10s
  disablePathMTUDiscovery: false

socks5:
  listen: 127.0.0.1:1080

http:
  listen: 127.0.0.1:8080

客户端启动命令:hysteria client -c config.yaml。如果需要在 Clash 中使用,可以通过 SOCKS5 代理接入。Clash 配置示例:

proxies:
  - name: hysteria2
    type: socks5
    server: 127.0.0.1
    port: 1080

proxy-groups:
  - name: auto
    type: url-test
    proxies:
      - hysteria2
    url: http://www.gstatic.com/generate_204
    interval: 300

6. 排障与性能诊断命令

当 Hysteria2 连接出现问题时,按以下顺序排查。

第一步,检查 UDP 端口是否可达。使用 nc -u -v example.com 443 测试 UDP 端口。如果返回 Connection refused,说明端口没有监听或防火墙拦截。如果超时,说明 UDP 包被丢弃。

第二步,检查 QUIC 握手。使用 curl --http3 https://example.com 测试 HTTP/3 是否可用。如果 curl 不支持 HTTP/3,可以用 hysteria client -c config.yaml 启动客户端,观察日志中的握手信息。

第三步,检查丢包和 RTT。使用 mtr --udp -P 443 example.com 查看 UDP 路径的丢包情况。注意 mtr 的 UDP 模式需要 root 权限。如果丢包集中在某一跳,说明该跳的 QoS 策略在起作用。

第四步,检查 Brutal 的实际发送速率。在服务器端使用 tcpdump -i eth0 -n udp port 443 -w hysteria.pcap 抓包,然后用 Wireshark 分析 QUIC 的发送速率和丢包率。Hysteria2 的日志中也会输出当前的带宽估计和丢包率。

第五步,调整 Brutal 参数。如果实际吞吐远低于目标带宽,可以尝试降低目标带宽或增加补偿系数。服务器端配置中的 bandwidth 字段是目标带宽,ignoreClientBandwidth 设为 false 时,服务器会使用客户端声明的带宽。如果设为 true,服务器会忽略客户端带宽,使用自己的带宽配置。

7. 晚高峰调优实战案例

某跨境企业专线,白天 Hysteria2 可以跑满 200Mbps,晚高峰跌到 10Mbps 以下。使用 mtr 发现丢包集中在出口网关,丢包率 25%。服务器端日志显示 Brutal 的目标带宽是 200Mbps,实际发送速率只有 15Mbps。调整策略如下。

第一步,降低目标带宽到 80Mbps。Brutal 在丢包率 25% 时,如果目标带宽过高,会导致大量重传和队列积压,实际吞吐反而下降。将目标带宽降到 80Mbps 后,实际吞吐提升到 45Mbps。

第二步,启用端口跳跃。将服务器监听端口从单一 443 改为 20000-50000 范围,客户端配置端口范围。运营商的限速策略基于五元组,端口跳跃后,限速策略无法稳定匹配,丢包率从 25% 降到 12%。

第三步,调整 QUIC 窗口。将 initStreamReceiveWindow 和 maxStreamReceiveWindow 从默认的 8MB 降到 2MB,减少内存占用和队列积压。将 maxIdleTimeout 从 30s 降到 15s,加快连接回收。

第四步,启用 fastOpen。客户端配置中 fastOpen: true 可以减少握手延迟,在丢包环境下效果明显。

调整后,晚高峰吞吐从 10Mbps 提升到 55Mbps,RTT 抖动从 45ms 降到 22ms。以下是调整前后的对比表格:

指标调整前调整后
目标带宽200 Mbps80 Mbps
实际吞吐10 Mbps55 Mbps
丢包率25%12%
RTT 抖动45 ms22 ms
连接建立时间320 ms180 ms

8. Brutal 与 BBRv3 的深度对比

BBRv3 是 Google 在 BBRv2 基础上改进的拥塞控制算法,主要优化了丢包恢复和公平性。BBRv3 在丢包率低于 5% 时表现优异,吞吐接近链路带宽。但在丢包率超过 10% 时,BBRv3 的拥塞窗口增长受丢包影响,吞吐急剧下降。

Brutal 的设计哲学与 BBRv3 完全不同。BBRv3 追求公平性和链路利用率,Brutal 追求用户指定的带宽目标。在丢包率高的链路上,Brutal 的吞吐优势明显,但代价是 RTT 抖动更大,且可能对其他流量造成不公平。在实际部署中,如果链路质量较好,BBRv3 是更好的选择;如果链路丢包严重,Brutal 可以维持可用带宽。

另一个关键区别是 Brutal 需要用户声明目标带宽。如果声明的带宽远高于实际链路容量,Brutal 会持续以高速率发送,导致大量丢包和重传,实际吞吐反而下降。所以 Brutal 的调优核心是找到合适的目标带宽,通常建议设置为实际链路带宽的 60-80%。

QUIC 的 0-RTT 和连接迁移特性也是 Hysteria2 的优势。在移动网络下,客户端 IP 变化时,QUIC 连接可以通过连接 ID 迁移,不需要重新握手。TCP 连接在 IP 变化时会中断,需要重新建立。对于移动办公场景,Hysteria2 的连接稳定性明显优于 TCP 代理。

9. 安全性与隐蔽性考量

Hysteria2 的 QUIC 流量在运营商看来是 UDP 流量,与普通的 QUIC 流量(如 HTTP/3)难以区分。但如果运营商对 UDP 流量进行深度包检测(DPI),Hysteria2 的握手特征可能被识别。Hysteria2 的握手使用 HTTP/3 风格的请求,与标准的 HTTP/3 握手相似,但认证字段和代理头部可能暴露特征。

为了提高隐蔽性,可以启用 masquerade 功能,将 Hysteria2 服务器伪装成一个正常的 HTTP/3 网站。客户端连接时,如果认证失败,服务器会返回一个正常的网页内容,而不是错误信息。这样即使 DPI 检测到 QUIC 流量,也无法区分是 Hysteria2 还是正常的 HTTP/3 流量。

端口跳跃也可以提高隐蔽性。如果服务器只监听一个端口,运营商的 DPI 可以针对该端口进行深度检测。端口跳跃后,DPI 需要跟踪多个端口,检测成本增加。但端口跳跃不是万能的,如果运营商对 UDP 流量进行全局限速,端口跳跃的效果有限。

10. 总结与建议

Hysteria2 的 Brutal 拥塞控制在极端弱网环境下具有明显优势,但需要合理配置目标带宽和端口跳跃。在实际部署中,建议先使用 mtr 和 tcpdump 诊断链路质量,然后根据丢包率调整目标带宽。端口跳跃可以有效对抗基于五元组的 QoS 限速,但需要正确配置服务器端的 DNAT 规则。

对于晚高峰丢包严重的场景,建议将目标带宽设置为实际链路带宽的 60-80%,启用端口跳跃,并调整 QUIC 窗口参数。如果链路质量较好,BBRv3 可能是更好的选择,因为它的公平性更好,RTT 抖动更小。

最后,Hysteria2 的调优是一个迭代过程,需要根据实际网络环境不断调整。建议在服务器端启用详细日志,定期分析 Brutal 的发送速率和丢包率,找到最优配置。

⚠️常见误区与避坑建议

  • •端口跳跃配置后忘记在服务器端添加 nftables/iptables DNAT 规则,导致客户端发送到随机端口的 UDP 包被内核直接丢弃,表现为连接随机中断或完全无法建立。
  • •Brutal 目标带宽设置过高(如直接填 1000Mbps),在 20% 丢包链路上导致发送速率远超链路容量,引发大量重传和队列积压,实际吞吐反而低于目标带宽的 10%。
  • •在 NAT 严格的网络环境下启用端口跳跃,运营商的 NAT 设备因五元组变化而重置连接,导致 QUIC 连接频繁中断,需要关闭端口跳跃或改用服务器端重定向模式。
🎯 完整用户决策旅程 (NEXT STEPS)

为您准备好的下一步需求承接

每个页面既要解决一个问题,也要为用户准备好最合理的下一步

TOPIC HUB · 专题中心

客户端配置与新手教程专区

图文详解各客户端智能分流与防风控配置。

前往客户端教程中心 →
DECISION & RECOMMEND · 选择指南

挑选适合开发者的稳定专线服务

核验专线延迟、双 ISP 纯净原生 IP 节点与流媒体实测数据。

查看稳定专线推荐 →
💡 机场搜 Decision Hub 承诺:本站严禁在信息型与教程页面进行强买强卖。我们致力于先帮您把技术问题解决透彻,再为您提供客观透明的多维选型参考。