如何在香港服务器的 Windows Server 2019 上配置 NIC RSS(接收端扩展),把万兆并发性能“掰”出来

凌晨 1:40,香港葵涌机房那台装着 Intel X710-DA2 的万兆服务器,在连续两晚的客户压测里都跑不满带宽:单流量程能上 9Gbps 左右,但一到多并发(几十条连接同时传)就掉速、抖动、CPU 单核顶满。客户应用是典型的小包高并发(API + 日志上报 + SMB 多会话),而我们“默认安装 + 默认驱动”的 Windows Server 2019 显然没给网卡把多核充分用起来。
那一刻我基本确定:RSS(Receive Side Scaling)没喂好。
下面就是我当晚从定位 → 规划 → 调参 → 复测的完整过程,以及踩到的坑和解决方案。你可以把它当成一份现场 SOP,里面的命令复制就能跑,逻辑清晰到足够新手上手,也细到能让老手少走弯路。
目标与环境
在 Windows Server 2019 上正确启用并调优 RSS,让多连接并发时充分利用多核,从而提高 10GbE 吞吐与稳定性,降低单核瓶颈与抖动。
现场环境(实参)
| 类别 | 规格 |
|---|---|
| 机房 | 香港葵涌(Kwai Chung) |
| 服务器 | 2U,双路 Intel Xeon Silver 4314(16C/32T * 2 = 64 逻辑核),内存 256GB |
| 主板/BIOS | 支持 NUMA;BIOS 电源策略已设定为 Performance |
| 操作系统 | Windows Server 2019 Datacenter,1809 基线,已打当月累积补丁 |
| 网卡 | Intel X710-DA2(双口 10GbE SFP+),驱动/固件来自 Intel 官方包(非 Windows Update) |
| 交换机 | 万兆 SFP+ 汇聚交换机(单链路,不做 LACP 聚合) |
| 业务特征 | 多会话并发、混合大小包,TCP/SMB、HTTP/HTTPS、gRPC 混合 |
| 工具 | iperf3(Windows 版)、PerfMon、PowerShell |
要点:尽量使用官方驱动(Intel PROSet/驱动包),Windows Update 自带驱动经常缺少高级属性入口或优化。
基线测试(调参前)
我先用 iperf3 做两个维度的基线:
单流
iperf3.exe -c <对端IP> -t 30
结果:9.3–9.6 Gbps(稳定)
多流并发(16 并发)
iperf3.exe -c <对端IP> -P 16 -t 30
结果:总吞吐仅 6.1–6.8 Gbps,PerfMon 看到某个逻辑核 %Util 高居不下(>90%),包处理明显集中。
这基本坐实:RSS 没把流分散到多核,或 VMQ/RSS 冲突导致 RSS 实际未生效。
调优思路图(先看路线,再下命令)
- 固件/驱动到位 → 让所有高级属性可见且受控
- BIOS/电源/NUMA → 保证 OS 能高效用核
- VMQ 与 RSS 的取舍 → 非虚拟化主机优先关 VMQ、开 RSS;Hyper-V 主机则按场景分层(详述见坑位)
- RSS 全局 + 网卡级启用 → netsh + PowerShell 双保险
- RSS 参数:Base/Max/NUMA → 让队列/核绑定更“亲 NUMA”
- 网卡高级属性 → RSS Queues、Interrupt Moderation、Rx/Tx Buffers、Jumbo
- RSC/LSO 等 Offload → 在并发小包下通常是收益项
- 验证与回归 → iperf3 + PerfMon + 连续压测
1. 驱动与固件:别用系统自带
到 Intel 官网下载适配 X710 的最新驱动/固件包(PROSet 28.x/27.x 及以上)。
安装 PROSet 后,设备管理器 → 网卡 → 高级,能看到更完整的RSS Queues、Interrupt Moderation、Receive Buffers、Jumbo Packet 等选项。
经验:Windows Update 自带驱动经常缺高级开关或缺少最佳默认值。网卡品牌换成 Broadcom/Mellanox 也同理:以官方包为准。
2. BIOS 与电源策略
BIOS:
关闭深度 C-States(或调低),启用 Turbo
打开 SR-IOV/VT-d(如后续可能用到)
确保 NUMA 未被隐藏(有的主板会提供 UMA/NUMA 选项)
OS 电源:
powercfg /setactive SCHEME_MIN
或“高性能 / Ultimate Performance(如可用)”
3. VMQ vs RSS:先理清谁在管中断
关键原则:
物理机直连业务(不跑 Hyper-V):关闭 VMQ,启用 RSS。
Hyper-V 宿主:宿主的物理 NIC 多由 VMQ 处理虚机流量;虚机网卡再用 vRSS 分散到虚机多核。宿主层的 RSS 与 VMQ 逻辑有冲突,需按角色分工。
非虚拟化(本场景) → 直接关 VMQ:
Get-NetAdapterVmq -Name "Ethernet 2"
Disable-NetAdapterVmq -Name "Ethernet 2"
如果你跑的是 Hyper-V,请参考“坑与案例”章节的虚拟化小节,不要生搬硬套。
4. 确认并启用 RSS(全局 + 网卡级)
4.1 全局 TCP RSS
netsh int tcp show global
netsh int tcp set global rss=enabled
4.2 网卡级 RSS(PowerShell)
# 查看网卡基本信息
Get-NetAdapter | ft Name, Status, LinkSpeed
# 查看 RSS 状态与绑定
Get-NetAdapterRss -Name "Ethernet 2" | fl *
# 开启 RSS(如果未启)
Enable-NetAdapterRss -Name "Ethernet 2"
验证点:Get-NetAdapterRss 应显示 Enabled=True,且能看到 NumaNode、BaseProcessorNumber/MaxProcessors 等字段。
5. 规划 RSS 的 CPU 绑定(Base / Max / NUMA)
目的:让网卡接收中断尽量落在同 NUMA 节点的一组核上,减少跨 NUMA 访存抖动;同时给并发留足够处理核数。
5.1 看看网卡属于哪个 NUMA 节点
Get-NetAdapterRss -Name "Ethernet 2" | ft Name, NumaNode
假设返回 NumaNode : 0。
5.2 规划核范围
我们的机器是 2 路、64 逻辑核。为避免与存储/应用主核冲突,我给网卡分 16 个逻辑核。假设 0–31 属于 NUMA 0,32–63 属于 NUMA 1(仅示例,实际以系统为准):
BaseProcessorNumber = 8(从 NUMA0 中部开始,避开 0–7 给系统/IO 中枢)
MaxProcessors = 16(让 RSS 可用 16 逻辑核)
5.3 设置
Set-NetAdapterRss -Name "Ethernet 2" `
-BaseProcessorNumber 8 `
-MaxProcessors 16 `
-NumaNode 0
# 再次查看
Get-NetAdapterRss -Name "Ethernet 2" | ft Name, Enabled, NumaNode, BaseProcessorNumber, MaxProcessors
说明:
MaxProcessors 是“RSS 允许用多少个处理器”;不是“最大处理器编号”。
很多场景不需要也不建议手动改 RSS 的 indirection table(散列重定向表),Windows 足够智能;只有在极端不均衡时再考虑微调。
6. 网卡高级属性:把“物理”也喂好
不同品牌/驱动的显示名略有差别,以下是 X710 上常见项,给出建议值与PowerShell 设置范例:
| 属性(可能的显示名) | 建议值 | 说明 |
|---|---|---|
| RSS Queues | 8 或 16 | 与 MaxProcessors 保持量级一致;万兆常用 8–16 |
| Interrupt Moderation | Enabled | 打开中断合并,配合下条速率 |
| Interrupt Moderation Rate | Adaptive(或 Medium) | 小包高并发选 Adaptive/Medium;低延迟极致场景可调 Low |
| Receive Buffers | 2048–4096 | 提高丢包抗性 |
| Transmit Buffers | 1024–2048 | 适中即可 |
| Jumbo Packet / Jumbo Frame | 9014 Bytes(端到端一致才开) | 路径上必须全端口一致,否则 MTU 不匹配会掉线/降速 |
| Large Send Offload (IPv4/IPv6) | Enabled | 保持默认开启 |
| Receive Side Coalescing (RSC) | Enabled | 有利于小包合并,降低 CPU |
示例命令(名称请以你驱动实际显示为准):
# RSS 队列数
Set-NetAdapterAdvancedProperty -Name "Ethernet 2" -DisplayName "RSS Queues" -DisplayValue "16"
# 中断调制
Set-NetAdapterAdvancedProperty -Name "Ethernet 2" -DisplayName "Interrupt Moderation" -DisplayValue "Enabled"
Set-NetAdapterAdvancedProperty -Name "Ethernet 2" -DisplayName "Interrupt Moderation Rate" -DisplayValue "Adaptive"
# 缓冲区
Set-NetAdapterAdvancedProperty -Name "Ethernet 2" -DisplayName "Receive Buffers" -DisplayValue "4096"
Set-NetAdapterAdvancedProperty -Name "Ethernet 2" -DisplayName "Transmit Buffers" -DisplayValue "2048"
# Jumbo(务必确认交换机/对端均一致)
Set-NetAdapterAdvancedProperty -Name "Ethernet 2" -DisplayName "Jumbo Packet" -DisplayValue "9014 Bytes"
7. RSC/LSO 等 Offload:全链路核对
7.1 全局 RSC(TCP 层)
netsh int tcp show global
netsh int tcp set global rsc=enabled
7.2 网卡级 RSC
Get-NetAdapterRsc -Name "Ethernet 2"
Enable-NetAdapterRsc -Name "Ethernet 2"
注意:极少数老旧设备/驱动在某些防火墙/抓包路径下会与 RSC 有兼容问题。出现异常时先 Disable-NetAdapterRsc 回退验证。
8. 验证:PerfMon + iperf3 双视角
8.1 iperf3 复测
单流:不做绝对指标(通常仍在 9.x Gbps)
并发(16/32 并发):
iperf3.exe -c <对端IP> -P 16 -t 60
iperf3.exe -c <对端IP> -P 32 -t 60
8.2 PerfMon 关键计数器
Processor Information% Processor Utility(看是否多核均摊)
Network Interface\Bytes Received/sec / Packets/sec
Network Interface\Output Queue Length(是否排队)
TCPv4/Connections Established、TCPv4/Segments/sec
Interrupts/sec(是否因中断过频导致抖动)
复测数据(调参前后对比)
| 指标 | 调参前(16 并发) | 调参后(16 并发) | 变化 |
|---|---|---|---|
| 总吞吐(Gbps) | 6.5 ±0.3 | 9.2 ±0.2 | ↑ +41% |
| p95 延迟(µs,应用端观测) | 780–1100 | 380–520 | ↓ |
| 单核最高占用 | 92%+ | 64% | ↓ |
| 丢包(对端抓包) | 可见少量重传 | 明显下降 | ↓ |
真实环境里,收益与业务包型/对端栈实现强相关;但RSS 正确启用 + 亲 NUMA 绑定,几乎总能把并发“掰”起来。
9. 常见坑与解决方案(真实踩坑记录)
9.1 VMQ/RSS 冲突
现象:Get-NetAdapterRss 显示启用,但流量仍扎堆在少数核;或 Get-NetAdapterVmq 显示 VMQ Enabled。
措施:非虚拟化主机直接 Disable-NetAdapterVmq,再 Enable-NetAdapterRss。Hyper-V 宿主请将物理 NIC 交给 VMQ,虚机中启用 vRSS,不要在宿主层硬上 RSS。
9.2 驱动来自 Windows Update
现象:设备管理器缺少“RSS Queues/Interrupt Moderation”等项,或参数改了不生效。
措施:安装官方驱动/PROSet,重启;必要时清理旧驱动残留。
9.3 Jumbo MTU 端到端不一致
现象:吞吐忽高忽低,Ping 带 DF 报文失败,偶发连接超时。
措施:交换机/对端/中间链路 全部统一 MTU(建议 9000/9014)。不确定就先全关 Jumbo,确认 RSS 生效后再逐段开。
9.4 NUMA 认知错误
现象:把 BaseProcessorNumber 设到了另一个 NUMA 节点,跨节点访存导致抖动。
措施:用 Get-NetAdapterRss 看 NumaNode,或 Get-Process -Id $PID | Select-Object -Expand ProcessorAffinity 等方法辅助确认核分布。
9.5 RSC 与特定内核/过滤驱动冲突
现象:装了抓包/杀软/NIDS 之类内核过滤后,小概率出现吞吐反而降低。
措施:逐项排查:先关 RSC(Disable-NetAdapterRsc),再看效果;必要时临时卸载冲突组件验证。
10. SMB 多通道(Bonus):如果你的并发主要是文件传输
Windows 的 SMB Multichannel 能并用 RSS/多队列,把会话分布到多核、多路径(如果你有多网口)。只要服务器与客户端都为 Server 2019+/Windows 10+,默认开启。
验证:
Get-SmbClientConfiguration | Select-Object EnableMultiChannel
Get-SmbServerConfiguration | Select-Object EnableMultiChannel
Get-SmbMultichannelConnection
如果你主要跑 SMB,多数情况下 RSS + SMB Multichannel 的组合收益可观;但请先把单端口 RSS 调顺,再考虑多口或多路径。
11. 一套可复制的“现场脚本清单”(可直接粘贴)
# 0) 基本检查
Get-NetAdapter | ft Name, Status, LinkSpeed
netsh int tcp show global
# 1) 关闭 VMQ(非虚拟化)
Disable-NetAdapterVmq -Name "Ethernet 2"
# 2) 全局开启 RSS + RSC
netsh int tcp set global rss=enabled
netsh int tcp set global rsc=enabled
# 3) 网卡开启 RSS 并绑定 NUMA0 的一段核(示例:从 8 开始,用 16 个逻辑核)
Enable-NetAdapterRss -Name "Ethernet 2"
Set-NetAdapterRss -Name "Ethernet 2" -BaseProcessorNumber 8 -MaxProcessors 16 -NumaNode 0
Get-NetAdapterRss -Name "Ethernet 2" | ft Name, Enabled, NumaNode, BaseProcessorNumber, MaxProcessors
# 4) 网卡高级属性(按实际显示名调整)
Set-NetAdapterAdvancedProperty -Name "Ethernet 2" -DisplayName "RSS Queues" -DisplayValue "16"
Set-NetAdapterAdvancedProperty -Name "Ethernet 2" -DisplayName "Interrupt Moderation" -DisplayValue "Enabled"
Set-NetAdapterAdvancedProperty -Name "Ethernet 2" -DisplayName "Interrupt Moderation Rate" -DisplayValue "Adaptive"
Set-NetAdapterAdvancedProperty -Name "Ethernet 2" -DisplayName "Receive Buffers" -DisplayValue "4096"
Set-NetAdapterAdvancedProperty -Name "Ethernet 2" -DisplayName "Transmit Buffers" -DisplayValue "2048"
# 5) RSC(网卡级)
Enable-NetAdapterRsc -Name "Ethernet 2"
Get-NetAdapterRsc -Name "Ethernet 2"
# 6)(可选)Jumbo,务必端到端一致后再开
# Set-NetAdapterAdvancedProperty -Name "Ethernet 2" -DisplayName "Jumbo Packet" -DisplayValue "9014 Bytes"
# 7) 统计与健康度
Get-NetAdapterStatistics -Name "Ethernet 2"
12. 快速回滚预案
关闭 RSC:Disable-NetAdapterRsc -Name "Ethernet 2"
关闭 RSS:Disable-NetAdapterRss -Name "Ethernet 2";全局 netsh int tcp set global rss=disabled
恢复 VMQ(若原本有虚拟化需求):Enable-NetAdapterVmq -Name "Ethernet 2"
高级属性逐项改回默认值(驱动 UI 可一键恢复)
13. FAQ(你可能会问)
Q:MaxProcessors 设多少合适?
A:万兆常见在 8–16 之间。看业务:小包/高并发/强加密可给多一些;纯大包吞吐给 8–12 通常够用。观察 CPU 分布是关键。
Q:必须手动改 indirection table 吗?
A:一般不需要。Windows 的散列分配已经很稳,只有在流异常集中(如固定 5tuple)且核不均衡时再考虑微调。
Q:Hyper-Threading 要关吗?
A:绝大多数情况下 不用关。RSS 与 HT 并不冲突,NUMA 亲和规划更重要。
Q:Jumbo 一定要开吗?
A:不是必须。开前先确认端到端一致。很多链路里有防火墙/负载均衡设备,容易忘记调 MTU。
结尾:走出机房前,我又看了一眼曲线
清晨 3:05,控制台上 32 并发压测的曲线贴着 9.4–9.6Gbps 稳稳地走,CPU 占用像被均匀切开,没有任何一个核再“爆红”。客户那边的延迟告警沉寂下来,只剩风扇在吹。我把最终参数写进变更单,拍了网卡配置界面的照片,又顺手把当晚的 iperf3 结果做了张小表发给群里——
“RSS 生效 & 亲 NUMA 绑定,问题解决。”
如果你也在香港的某个机房里为同样的抖动发愁,不妨照着这套流程来一遍。驱动到位、VMQ/RSS 分工清晰、RSS 参数亲 NUMA、配合合适的中断与缓冲——万兆并发的潜力,就在这里被一点点“掰”出来。
附:变更记录模板(可抄)
变更对象:Ethernet 2 (Intel X710-DA2)
变更项:
- 关闭 VMQ;启用 RSS(Base=8、Max=16、NUMA=0)
- RSS Queues=16;Interrupt Moderation=Enabled/Adaptive
- Rx Buffers=4096;Tx Buffers=2048
- RSC=Enabled;(Jumbo 暂不开/或统一 9014)
- 回滚:按“快速回滚预案”执行
- 验证:iperf3(16/32 并发 60s)、PerfMon 指标、业务端 p95/99
- 影响范围:网络栈;业务低峰期实施
- 风险评估:低(具备逐项回退与可观测性)
祝你一把到位、一次成功