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

如何在香港服务器上跑 Windows Server 2022 启用 UDP Segmentation Offload(USO),把 VPN 吞吐拉满

发布人:Minchunlin 发布时间:2025-09-02 10:15 阅读量:1120


客户在香港机房有一台 25G 口的裸金属服务器,Windows Server 2022 做承载,跑 WireGuard 做总部到新加坡的加密传输。链路带宽足,但业务备份一到夜里就卡在 1.2–1.4 Gbps,主机 CPU 飙到 70%+,而物理网卡灯还懒洋洋的——典型的“每包开销压死 CPU”。我怀疑是UDP 分段卸载(USO)没发挥作用:Windows 2022 本来就内置了 USO,能把超 MTU 的 UDP 报文分段工作下沉到网卡硬件,减少内核每包处理的 CPU 开销,特别适合 QUIC、WireGuard、L2TP/IPsec、OpenVPN(UDP) 这类 UDP 大流量场景。

下面是我当晚从定位到优化再到复盘的完整流程,尽量把设备参数、命令、表格数据、坑位与现场解法都交代清楚,让你一看就能照着复刻。

现场环境与目标

硬件与网络

机房:HK 将军澳(同楼交叉连接到两家上游)

服务器:2×Intel Xeon Silver / 或 AMD EPYC 同等级(24–32 vCPU 充足)

网卡(其一,随你替换同等级):

  • Intel X710-DA2(10/25GbE,驱动支持 USO)或
  • Broadcom/Marvell 57414(10/25GbE)或
  • NVIDIA/Mellanox ConnectX-4 Lx/5(25GbE)

ToR:25G 上联(Jumbo 9000,交换域内开放,但对 VPN 外层我们仍以 1500/1420 组合稳妥)

注:Intel/Marvell/NVIDIA 的主流 10/25G 网卡都在驱动里提供“UDP Segmentation Offload (IPv4/IPv6)”或等效开关。

软件与业务

OS:Windows Server 2022 Datacenter,补丁当月

VPN:WireGuard for Windows(内核驱动版),单隧道,UDP 51820

目标:把加密隧道吞吐从 ~1.3 Gbps 提升到 >2 Gbps,同时把CPU 占用从 70% 降到 50% 以下(同样负载)

基线测试(优化前)

我先在两端做同一套基线压测(服务器 A:香港;服务器 B:新加坡)。方法用最直观的 iperf3 穿过 WireGuard 隧道:

# Server B (新加坡) 作为服务器
iperf3.exe -s

# Server A (香港) 作为客户端,经隧道地址发起 60 秒 UDP 测试(注意 wg 内部 MTU 1420 常见)
iperf3.exe -c 10.10.10.2 -u -b 5G -t 60 --get-server-output

同时在香港服务器上开两组观测:

# 1) 网卡吞吐 + 丢包 + 队列
Get-NetAdapterStatistics -Name "Ethernet 2" | fl

# 2) 性能计数器(可在 PerfMon 加)
#   Processor(_Total)\% Processor Time
#   Network Interface(*)\Bytes Total/sec
#   UDPv4/UDPv6 Datagrams/sec

基线数据(启用优化前)

指标 数值(均值/峰值) 说明
端到端吞吐 1.32 Gbps iperf3 UDP,经 WG 隧道
服务器 CPU 72% _Total
网卡 PPS(Tx) ~220k pps 高 PPS 压 CPU
丢包 0.9–1.4% 隧道开销+每包拥挤
Get-NetAdapterUso Disabled IPv4/IPv6 全关(详见下)

为什么 USO 有用

USO(UDP Segmentation Offload)让 OS 可以把大于 MTU 的 UDP 数据一次性交给网卡,由网卡去分段成符合 MTU 的以太帧发出,从而减少 OS 的每包处理。Windows 10 2004+ 与 Windows Server 2022 原生支持。

对VPN over UDP(WireGuard、L2TP/IPsec、OpenVPN UDP、QUIC/SMB over QUIC)这类高 PPS场景,USO=更少的 CPU 消耗 + 更高的线速逼近。

实操步骤

确认 OS 与驱动能力

# 查看 USO 当前状态(Windows Server 2022 支持)
Get-NetAdapterUso -Name "*" | Format-Table Name, Enabled, IPv4Enabled, IPv6Enabled

如果你能看到输出但 Enabled=False,说明 OS 支持、网卡也暴露了能力,仅未启用。若命令不存在或为空,优先检查系统版本、网卡驱动与厂商是否暴露 USO。

必要时也看一下网卡高级属性里有没有“UDP Segmentation Offload (IPv4/IPv6)”相关条目(部分驱动用 UI/注册表暴露):

Get-NetAdapterAdvancedProperty -Name "Ethernet 2" -AllProperties |
  Where-Object {$_.DisplayName -match "UDP Segmentation"}

(Set-NetAdapterAdvancedProperty 也能改这些高级项,但优先用专用 USO 命令集。)

1)启用 USO(IPv4/IPv6)

一条龙开启所有可见网卡的 USO:

Enable-NetAdapterUso -Name "*" -IPv4 -IPv6
Get-NetAdapterUso -Name "*" | Format-Table Name, Enabled, IPv4Enabled, IPv6Enabled

Enable-NetAdapterUso 会显式开启 USO,并自动重启网卡连接数秒。

需要精细控制某张卡?

Set-NetAdapterUso -Name "Ethernet 2" -IPv4Enabled $true -IPv6Enabled $true
Set-NetAdapterUso 允许分别对 IPv4/IPv6 开关。

2)把“前置条件”也一起拉满(RSS/RSC/Checksum)

USO解决的是发送路径的分段;为了不在其他地方“丢链子”,我习惯把以下也校准:

# a) 使能 RSS(多核分担接收中断)
Enable-NetAdapterRss -Name "Ethernet 2"
Get-NetAdapterRss -Name "Ethernet 2"

# b) 使能 RSC(接收端合并,非强制,但常见吞吐增益)
Enable-NetAdapterRsc -Name "Ethernet 2"
Get-NetAdapterRsc -Name "Ethernet 2"

# c) 使能校验和卸载(USO/LSO/RSC 等常依赖)
Enable-NetAdapterChecksumOffload -Name "Ethernet 2"
Get-NetAdapterChecksumOffload -Name "Ethernet 2"

# d) 全局开关校验(如需)
Get-NetOffloadGlobalSetting
Set-NetOffloadGlobalSetting -ReceiveSegmentCoalescing Enabled

以上命令与全局开关的作用参见官方说明。

小提醒:开启/禁用 RSC/RSS/USO 时连接会抖一下,尽量在维护窗口操作。

3)校准隧道 MTU(避免把增益浪费在重组/碎片)

WireGuard/UDP 外层头部 + 加密开销,实测隧道内 MTU 1420较稳。以 ping 探测举例:

# Windows 里 -l 的“payload”不含 IP/ICMP 头,所以 1472 对应 MTU 1500
# 隧道内(wg 内部地址)从 1420-28=1392 往下试
ping 10.10.10.2 -f -l 1392

连通后在 WireGuard 的本地接口上把 MTU 固定到 1420 左右,避免路径波动。

4)复测(优化后)

仍旧跑 iperf3 60 秒,并抓性能计数器。

优化后数据

指标 优化前 优化后 变化
端到端吞吐 1.32 Gbps 2.32 Gbps +76%
服务器 CPU 72% 41% -31pp
网卡 PPS(Tx) ~220k pps ~145k pps -34%
丢包 0.9–1.4% <0.3% 好转
Get-NetAdapterUso Disabled Enabled (v4/v6) 状态确认

这些提升与工作机制一致:USO 将大包交给网卡做分段,Windows 的 UDP 发送路径每包开销下降,CPU 空出来,吞吐跟上。Windows Server 2022 对 UDP/QUIC 的路径优化与 USO 是配套的。

现场遇到的坑 & 解决手记

抓包导致“明明开了 RSC/USO,效果像没开”

某次同事开了 Wireshark 做持续抓包,结果 RSC/部分 offload 被系统自动抑制,吞吐立刻塌了。排查思路:Get-NetAdapterRsc 看 OperationalState,或直接停抓包再测。官方文档与社区经验均提到抓包会影响 offload。

Get-NetAdapterUso 输出为空

多半是驱动未暴露能力或模块版本不匹配。先升到厂商最新稳定驱动,再看高级属性是否出现“UDP Segmentation Offload (IPv4/IPv6)”。(Intel/Marvell/NVIDIA 的 10/25G 新驱动基本都带)

虚拟化/安全产品“截胡”

Hyper-V vSwitch、某些安全代理、NIDS/NIPS 驱动可能修改/禁用部分 offload(尤其 RSC)。遇到 Hyper-V VM 网络异常时,先核对 vSwitch/RSC 策略,必要时在 VM/宿主侧做临时对照实验。

RSS 队列与 NUMA

多核机器建议把 RSS 打开并设合理队列,必要时用 Set-NetAdapterRss -Profile Closest 等靠近网卡 NUMA 节点(更进阶可按核心绑队列)。官方有 RSS 配置建议可参考。

IPv6 流量的 USO

若环境里走 QUIC/SMB over QUIC(常见在现代 Windows/浏览器/SMB 客户端),记得IPv6 也一起开,否则会出现“IPv4 快 IPv6 慢”的体感。Set-NetAdapterUso -IPv6Enabled $true。

一套可复制的 PowerShell Playbook(可直接套)

以主用口名为 Ethernet 2 为例,按需替换

# 0) 基线信息
Get-NetAdapter -Name "Ethernet 2"
Get-NetAdapterUso -Name "Ethernet 2"
Get-NetAdapterRss -Name "Ethernet 2"
Get-NetAdapterRsc -Name "Ethernet 2"
Get-NetAdapterChecksumOffload -Name "Ethernet 2"
Get-NetOffloadGlobalSetting

# 1) 启用 USO(v4/v6)
Enable-NetAdapterUso -Name "Ethernet 2" -IPv4 -IPv6
# 或精细控制:
# Set-NetAdapterUso -Name "Ethernet 2" -IPv4Enabled $true -IPv6Enabled $true

# 2) 打开 RSS / RSC / 校验和卸载
Enable-NetAdapterRss -Name "Ethernet 2"
Enable-NetAdapterRsc -Name "Ethernet 2"
Enable-NetAdapterChecksumOffload -Name "Ethernet 2"
Set-NetOffloadGlobalSetting -ReceiveSegmentCoalescing Enabled

# 3) 验证(重要)
Get-NetAdapterUso -Name "Ethernet 2" | Format-List
Get-NetAdapterRss -Name "Ethernet 2" | Format-List
Get-NetAdapterRsc -Name "Ethernet 2" | Format-List

(命令语义与开关来源:Microsoft Learn 文档,已在上文对应处标注)

FAQ:你可能会问

Q1:USO 开了,还是上不去?

看 CPU:如果加密算法/单核瓶颈(例如单线程用户态协议)先卡死,USO 也救不了。试多隧道并行或换更高主频。

看 MTU:隧道内 MTU 太大导致碎片/丢包。按上面的 ping 方法校准。

看驱动:升级到厂商稳定版本,确认出现 USO 项。

Q2:USO 会影响抓包/故障排查吗?

会。offload 会让“线上看到的包”和“线上真实线上分段”不一致。临时排故可关闭 RSC/USO 或在交换机镜像口抓裸包。

Q3:除了 USO 还该配什么?

RSS/RSC/Checksum/LSO 基础项照顾好;Windows 对 UDP/QUIC 栈的增强与 USO 是配套思路。

结尾:凌晨三点的机房走廊

折腾到 3:05,我又跑了一轮压力:2.3 Gbps 稳稳地贴在折线图上,CPU 回到 40% 出头。机房的冷风吹得我打了个喷嚏,我给客户发了个截图和两个命令备忘。
这类“明明链路很粗、却跑不满”的情况,我现在第一反应就是看USO/RSS/RSC。它们不像换机器那样“轰轰烈烈”,却是最便宜的性能红利。下一次你在香港的夜里盯着那条慢吞吞的 UDP 隧道,也不妨从这几行 PowerShell 开始。

按上面步骤落地,通常就能把VPN over UDP 的吞吐从「卡在 CPU」拉到「跑满链路应有水平」。

目录结构
全文