增加 Windows Server 2022 上的 TCP 连接数 可以调整10000个连接, 增加UDP连接数 可以调整5000个 你可以通过修改注册表来实现。请按照以下步骤进行操作
Windows Server TCP 高并发核心注册表参数合集完整解构
覆盖参数:
TcpNumConnections/MaxTcpConnections/MaxUserPort/TcpTimedWaitDelay/MaxFreeTcbs/MaxHashTableSize适用系统:Windows Server 2019/2022
✅ 各参数底层原理、依赖、链路、配套、边界
1. TcpNumConnections
注册表路径:HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpNumConnections
- 底层原理:tcpip.sys 内核参数,控制系统整机 TCP TCB(TCP 控制块)最大数量。TCB 是内核中维护一条完整 TCP 四元组连接的核心数据结构,三次握手完成后就会占用 TCB;到达上限后新 TCP 连接直接拒绝。默认值
0x00FFFFFE≈16777214,默认几乎不构成瓶颈。 - 依赖文件:tcpip.sys、registry.sys
- 依赖关系:系统启动阶段一次性加载,修改后必须重启生效;该约束在内核协议栈层面,优先级低于 AFD 套接字上限。
- 逻辑链路:应用创建 TCP Socket → afd.sys 校验
MaxTcpConnections→ 下发 tcpip.sys 分配 TCB → 判断当前 TCB 数量 <TcpNumConnections,不满足直接返回资源不足。 - 配套链:
MaxFreeTcbs、MaxHashTableSize、非分页池监控;排查命令Get-NetTCPConnection统计当前 TCB 数量。 - 边界:只管控已完成三次握手的连接;SYN 队列中的半连接不计入;即使调大,内核非分页池不足依然无法分配 TCB。
2. MaxTcpConnections
注册表路径:HKLM\SYSTEM\CurrentControlSet\Services\AFD\Parameters\MaxTcpConnections
- 底层原理:afd.sys(Winsock 辅助驱动)全局 TCP Socket 句柄上限。管控用户态程序通过 Winsock 创建的 TCP 套接字总数,和
MaxUdpConnections是成对配套参数。当应用调用 socket () 新建 TCP 套接字时,AFD 做计数校验,触顶直接拒绝。 - 依赖文件:afd.sys、ws2_32.dll、registry.sys
- 依赖关系:开机加载,重启生效;上层套接字约束,优先级高于 TcpNumConnections;内核原生 TCP 流量(不经过 Winsock AFD)不受限制。
- 逻辑链路:应用 ws2_32.dll → WSASocket → IRP 下发 afd.sys → 判断当前 TCP socket 计数 < MaxTcpConnections → 通过后再进入 tcpip.sys 分配 TCB。超限返回
WSAENOBUFS(10055)。 - 配套链:MaxUdpConnections;排查
Get-NetTCPConnection、进程句柄查看。 - 边界:区分【Socket 句柄数】和【TCP 连接数】;一个监听 Socket 可以接纳成千上万个客户端 TCP 连接,不要混淆两个指标。
3. MaxUserPort
注册表路径:HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort
- 底层原理:定义客户端出站 TCP 连接可用的动态本地端口上限。客户端主动向外发起连接时,系统自动分配本地临时端口,端口池耗尽后无法新建出站连接。默认范围:49152~65535。
- 依赖文件:tcpip.sys、registry.sys
- 依赖关系:重启生效;仅影响主动发起连接(客户端),不影响本机监听入站服务。
- 逻辑链路:程序发起 connect () → tcpip.sys 从动态端口池分配本地端口 → 端口池耗尽直接新建失败。
- 配套链:
TcpTimedWaitDelay;PowerShell 查看Get-NetTCPSetting - 边界:入站监听服务不消耗动态端口;大量短连接场景(爬虫、网关)极易卡在这个参数,而不是 TCB 上限。
4. TcpTimedWaitDelay
注册表路径:HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay
- 底层原理:控制 TCP 连接关闭后进入
TIME_WAIT状态的持续时长(单位:秒)。TIME_WAIT 用于保证远端收到 FIN 包、防止延迟重复报文干扰新连接。默认 240 秒。缩短该值可以快速回收动态端口,释放端口资源。 - 依赖文件:tcpip.sys、registry.sys
- 依赖关系:重启生效;配合 MaxUserPort 解决短连接大量 TIME_WAIT 端口耗尽问题。
- 逻辑链路:TCP 四次挥手完成 → 连接进入 TIME_WAIT 定时器倒计时 → 超时后释放 TCB + 回收本地端口。
- 配套链:MaxUserPort;
Get-NetTCPConnection | Where-Object State -eq TimeWait统计 - 边界:过度缩短会带来脏报文、端口复用冲突风险;生产环境不建议低于 30s。
5. MaxFreeTcbs
注册表路径:HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxFreeTcbs
- 底层原理:内核预分配空闲 TCB 缓存池上限。系统预先创建一批空闲 TCB,新连接直接复用,避免实时申请非分页内存带来性能损耗;空闲 TCB 超过该阈值时内核自动回收释放内存。
- 依赖文件:tcpip.sys、registry.sys
- 依赖关系:重启生效;高并发突峰场景非常关键。
- 逻辑链路:新建 TCP 连接 → 优先从空闲 TCB 池取用;池空才向系统申请新非分页内存;空闲连接释放后 TCB 回收入池,池满则直接释放。
- 配套链:TcpNumConnections、MaxHashTableSize、非分页池监控
- 边界:预分配 TCB 会持续占用非分页内存,设置过大容易内存压力。
6. MaxHashTableSize
注册表路径:HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxHashTableSize
- 底层原理:TCP 四元组哈希表大小。内核依靠哈希表快速根据【源 IP: 源端口:目的 IP: 目的端口】查找 TCB;哈希表过小,大量 TCP 连接时哈希冲突飙升,查询性能急剧下降、CPU 上涨。值必须是 2 的幂(512/1024/2048/4096/8192 等)。
- 依赖文件:tcpip.sys、registry.sys
- 依赖关系:重启生效;连接量级越大,该参数越重要。
- 逻辑链路:报文入栈 → 四元组计算 hash → 在哈希表检索对应 TCB;冲突越多遍历开销越高。
- 配套链:TcpNumConnections、性能监控(网卡 / CPU)
- 边界:不是连接硬限制,属于性能参数,不会直接拒绝连接,但高并发下会引发 CPU 瓶颈。
✅ 统一完整校验链路(优先级从上至下)
应用调用ws2_32.dll创建TCP套接字
↓
afd.sys校验 MaxTcpConnections(套接字上限)→ 超限返回 WSAENOBUFS(10055)
↓
tcpip.sys处理TCP连接
├─ 客户端出站:校验动态端口池(MaxUserPort)是否还有可用端口
├─ TCB分配校验:当前TCB总数 < TcpNumConnections;优先复用MaxFreeTcbs空闲池
├─ 四元组检索依赖 MaxHashTableSize哈希表
└─ 连接关闭后,TCB进入TIME_WAIT(TcpTimedWaitDelay)定时回收
↓
资源不足时返回 STATUS_INSUFFICIENT_RESOURCES
✅ 配套工具与错误码说明
- 查看 TCP 连接
# PowerShell推荐
Get-NetTCPConnection | Select LocalAddress,LocalPort,RemoteAddress,RemotePort,State
# 传统命令
netstat -ano
- PowerShell 原生 TCP 配置(无需改注册表,部分参数热生效)
# 查看TCP全局配置
Get-NetTCPSetting
# 修改TCP参数(部分无需重启)
Set-NetTCPSetting -SettingName InternetCustom -TcpTimedWaitDelay 30
⚠️ 注意:
Set-NetTCPSetting只能控制 Modern TCP 栈参数,无法修改 AFD 系列 MaxTcpConnections,AFD 参数依然需要注册表 + 重启。
- 核心错误码
WSAENOBUFS (10055):AFD 套接字上限 / 内核缓冲区资源不足STATUS_INSUFFICIENT_RESOURCES:内核非分页池耗尽、TCB 分配失败
✅ 配套一键部署 PowerShell 脚本(Server2022)
# Tcpip 内核TCP参数
$regTcpip = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
New-ItemProperty -Path $regTcpip -Name "TcpNumConnections" -Value 16000000 -PropertyType DWord -Force
New-ItemProperty -Path $regTcpip -Name "MaxUserPort" -Value 65534 -PropertyType DWord -Force
New-ItemProperty -Path $regTcpip -Name "TcpTimedWaitDelay" -Value 30 -PropertyType DWord -Force
New-ItemProperty -Path $regTcpip -Name "MaxFreeTcbs" -Value 200000 -PropertyType DWord -Force
New-ItemProperty -Path $regTcpip -Name "MaxHashTableSize" -Value 65536 -PropertyType DWord -Force
# AFD TCP套接字上限(配套MaxUdpConnections)
$regAfd = "HKLM:\SYSTEM\CurrentControlSet\Services\AFD\Parameters"
if (-not (Test-Path $regAfd)){New-Item -Path $regAfd -Force}
New-ItemProperty -Path $regAfd -Name "MaxTcpConnections" -Value 100000 -PropertyType DWord -Force
Write-Host "配置写入完成,全部参数需要重启服务器生效!"
✅ 整体边界汇总
- 所有注册表参数内核启动阶段加载,修改后必须重启(
Set-NetTCPSetting部分参数热生效) - 资源约束优先级:AFD 套接字上限 > TCB 总数 > 动态端口 > 非分页内存
- MaxHashTableSize 不限制连接数量,只影响高并发下 CPU 性能
- 区分场景:入站服务瓶颈一般是 TCB/AFD;大量短连接出站瓶颈是 MaxUserPort+TIME_WAIT
- 虚拟化、容器、WFP 防火墙会叠加额外连接限制,该组参数仅作用主机原生 TCP/AFD 栈
增加 Windows Server 2022 上的 TCP 连接数,你可以通过修改注册表来实现。请按照以下步骤进行操作:
打开注册表编辑器:按下 Win + R 键,在运行框中输入 "regedit",然后点击 "确定"。
导航到以下注册表路径:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters。
在 “参数” 键下创建一个新的 DWORD (32 位)值。右键点击 “参数”,选择 "新建" -> "DWORD (32 位) 值"。
将新创建的 DWORD 值命名为 "MaxConnections"(不包括引号),然后按回车键。
双击 "MaxConnections" 值,进入编辑模式,将数值数据设置为你期望的 TCP 连接数。例如,如果你想要增加到 10000 个连接,将数值数据设置为 10000。
确认数值数据后,点击 "确定"。
关闭注册表编辑器。
重新启动服务器,使更改生效。
请注意,增加 TCP 连接数可能会对系统资源产生影响,尤其是内存和处理器。确保服务器具备足够的硬件资源来处理更多的 TCP 连接,并仔细评估增加连接数的可能影响。
对于 Windows Server 2022,最大 TCP 连接数取决于多个因素,例如硬件资源、操作系统版本和网络堆栈配置等。然而,Windows Server 2022 默认情况下支持相当大的 TCP 连接数。
在默认情况下,Windows Server 2022 的最大 TCP 连接数可以达到上万个,远远超过一般情况下的需求。大多数应用程序不会达到这样的连接数限制。
如果你实际上需要增加 TCP 连接数,你可以按照前面提到的方法修改注册表中的 "MaxConnections" 值来调整。但是,请注意在增加连接数之前,确保服务器硬件资源和网络堆栈能够支持更多的连接。另外,增加连接数可能需要额外的系统和网络优化。
MaxConnections(Tcpip\Parameters)完整解构
⚠️ 核心前置结论:
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxConnections不是微软官方认可的标准有效注册表项! 该键属于网络博客流传的错误参数,tcpip.sys 内核不会读取这个键,创建并设置数值不会生效,无法限制 / 提升 TCP 连接数; Windows Server 2022 真正管控整机 TCP 并发连接上限的标准参数:TcpNumConnections;管控 AFD 套接字上限的是AFD\Parameters\MaxTcpConnections(和前面 UDP MaxUdpConnections 配套)。
用户文中流传操作: 路径:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters新建 DWORDMaxConnections,设置目标 TCP 连接数(示例 10000)
✅ 底层原理
MaxConnections本身无内核解析逻辑:tcpip.sys 在系统启动加载 Tcpip\Parameters 注册表配置时,代码内没有读取MaxConnections变量的分支,写入该值不会在内核生成任何连接计数器上限。属于互联网运维文章以讹传讹的参数。- Windows TCP 真实连接管控模型:
TcpNumConnections:tcpip.sys 层面整机TCB(TCP 控制块)总上限,控制系统所有已完成三次握手的 TCP 连接总数,默认 0x00FFFFFE≈16777214AFD\Parameters\MaxTcpConnections:afd.sys 层面用户态 Winsock TCP Socket 句柄上限(和之前 UDPMaxUdpConnections成对)MaxFreeTcbs:预分配空闲 TCB 池上限,非分页内存资源硬约束MaxUserPort:出站动态端口范围上限(客户端大量发起连接时瓶颈)
- 真实新建 TCP 连接校验链路:应用创建 socket → afd.sys 校验 MaxTcpConnections → tcpip.sys 分配 TCB,校验 TcpNumConnections/MaxFreeTcbs、非分页池。
- 很多运维误以为改
MaxConnections生效,本质是同时改了其他真实参数或重启后系统资源状态变化带来的错觉。
✅ 依赖文件
| 文件 | 路径 | 核心作用 |
|---|---|---|
| tcpip.sys | C:\Windows\System32\drivers\tcpip.sys |
TCP 协议栈、TCB 管理、读取TcpNumConnections(不识别 MaxConnections) |
| afd.sys | C:\Windows\System32\drivers\afd.sys |
Winsock 辅助驱动、套接字计数,读取MaxTcpConnections |
| registry.sys | 内核 | 系统启动时加载 Tcpip 注册表配置 |
| ws2_32.dll | System32 | 用户态 Winsock API 入口,socket/accept/connect 调用 |
| ndis.sys | System32\drivers\ndis.sys |
NDIS 网络驱动框架 |
✅ 依赖关系
- 该参数无任何内核依赖:即使创建 MaxConnections,tcpip.sys 启动时直接忽略该注册表值,不加载进内核内存。
- 真实 TCP 上限的约束优先级(从上层到内核):
AFD MaxTcpConnections(Socket上限)>TcpNumConnections(整机TCB上限)>MaxFreeTcbs空闲TCB池> 内核非分页池内存 - 生效前提区分:
TcpNumConnections/MaxTcpConnections:重启服务器才加载- 动态端口 MaxUserPort:重启生效
- 权限约束:修改 Tcpip 注册表项需要管理员权限。
✅ 逻辑链路(区分【网传 MaxConnections】和【真实有效链路】)
❌ 网传 MaxConnections 的实际链路(无效)
用户创建注册表MaxConnections → 写入注册表hive
→ 系统重启,registry.sys加载Tcpip参数
→ tcpip.sys遍历Tcpip\Parameters,不存在处理MaxConnections的逻辑,直接丢弃该配置
→ 新建TCP连接时,完全不会校验这个数值,连接上限不受该值控制
✅ Windows Server2022 真实 TCP 并发校验链路(标准有效)
应用调用ws2_32.dll → WSASocket/accept创建TCP套接字
→ IRP下发afd.sys → 判断是否达到 AFD MaxTcpConnections
└─触顶 → 返回WSAENOBUFS(10055)
→ afd调用tcpip.sys分配TCB
→ tcpip.sys校验 当前TCB总数 < TcpNumConnections、空闲TCB池、非分页池
✅ 通过 → 建立TCP连接
❌ 不通过 → 拒绝新建连接
✅ 配套链
- 标准有效配套注册表项(真正调 TCP 并发)
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpNumConnections:整机 TCB 总数上限HKLM\SYSTEM\CurrentControlSet\Services\AFD\Parameters\MaxTcpConnections:全局 TCP 套接字上限(和 MaxUdp 配套)MaxUserPort、TcpTimedWaitDelay、MaxFreeTcbs、MaxHashTableSize
- 查看当前 TCP 连接:
Get-NetTCPConnection、资源监视器、netstat - 错误码:WSAENOBUFS (10055)、STATUS_INSUFFICIENT_RESOURCES
- PowerShell 网络配置命令:
Set-NetTCPSetting - 配套之前 UDP 参数:
AFD\Parameters\MaxUdpConnections
✅ 边界(重点坑点)
- 核心坑:MaxConnections 不生效,属于网上流传错误参数,微软官方文档没有定义该 Tcpip 参数,生产环境不要依赖此配置。
- 容易混淆两组参数位置:
Tcpip\Parameters\TcpNumConnections:tcpip 内核 TCB 总数AFD\Parameters\MaxTcpConnections:afd 套接字上限(和 UDP MaxUdpConnections 同组)
- 就算 TcpNumConnections 设置极大,非分页池内存不足依然无法新建 TCP 连接,这是高并发网关最常见瓶颈。
- 区分「服务器监听入站连接」和「客户端大量出站连接」:客户端瓶颈往往是
MaxUserPort动态端口不足,不是 TcpNumConnections。 - 容器、Hyper-V 虚拟网卡、WFP 过滤驱动会叠加额外独立连接限制。
- 与之前 UDP 参数概念区分:UDP 无 TCB,只受 AFD 套接字计数 MaxUdpConnections 管控;TCP 存在 AFD 套接字 + 内核 TCB 两层限制。
✅ 【生产可用・正确版本 PowerShell 脚本】(替代无效的 MaxConnections)
# ========== 正确:TcpNumConnections 整机TCP TCB上限 ==========
$regTcpip = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
New-ItemProperty -Path $regTcpip -Name "TcpNumConnections" -Value 10000 -PropertyType DWord -Force
# ========== 正确:AFD层TCP套接字上限(配套UDP MaxUdpConnections) ==========
$regAfd = "HKLM:\SYSTEM\CurrentControlSet\Services\AFD\Parameters"
if (-not (Test-Path $regAfd)) { New-Item -Path $regAfd -Force }
New-ItemProperty -Path $regAfd -Name "MaxTcpConnections" -Value 10000 -PropertyType DWord -Force
Write-Host "配置写入完成,必须重启服务器生效"
✅ 高频故障汇总
- 设置 MaxConnections 后并发上限无变化:该参数内核不识别,完全无效
- TcpNumConnections 已经很大,但依然报 10055:触达 AFD MaxTcpConnections 或者系统非分页池耗尽
- 大量出站连接无法建立:瓶颈是 MaxUserPort 动态端口范围不足,不是 TCB 上限
在 Windows Server 2022 上增加 UDP 连接数需要通过修改注册表来实现。请按照以下步骤进行操作:
打开注册表编辑器:按下 Win + R 键,在运行框中输入 "regedit",然后点击 "确定"。
导航到以下注册表路径:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Parameters。
在 "参数" 键下创建一个新的 DWORD (32 位) 值。右键点击 "参数",选择 "新建" -> "DWORD (32 位) 值"。
将新创建的 DWORD 值命名为 "MaxUdpConnections"(不包括引号),然后按回车键。
双击 "MaxUdpConnections" 值,进入编辑模式,将数值数据设置为你期望的 UDP 连接数。例如,如果你想要增加到 5000 个连接,将数值数据设置为 5000。
确认数值数据后,点击 "确定"。
关闭注册表编辑器。
重新启动服务器,使更改生效。
请注意,增加 UDP 连接数可能会对系统资源产生影响,尤其是网络带宽和处理器。确保服务器具备足够的硬件资源来处理更多的 UDP 连接,并仔细评估增加连接数的可能影响。
对于 Windows Server 2022,默认情况下没有明确的最大 UDP 连接数限制。UDP 连接数的限制通常由可用的系统资源和网络堆栈配置决定。
Windows Server 2022 支持更大数量的 UDP 连接,远远超过一般的需求。大多数应用程序不会达到 UDP 连接数的极限。
如果你需要增加 UDP 连接数,可以按照前面提到的方法修改注册表中的 "MaxUdpConnections" 值来进行调整。但是,请务必在增加连接数之前,进行充分的评估,确保服务器硬件资源和网络能够支持更多的连接。增加连接数可能需要进行额外的系统和网络优化。
AFD 配套注册表项合集完整解构
覆盖参数:
MaxTcpConnections/DefaultSendWindow/DefaultReceiveWindow/NonPagedPoolQuota路径统一前缀:HKLM\SYSTEM\CurrentControlSet\Services\AFD\Parameters适用系统:Windows Server 2019 / 2022,配套前面MaxUdpConnections
1. MaxTcpConnections
注册表路径:HKLM\SYSTEM\CurrentControlSet\Services\AFD\Parameters\MaxTcpConnections
- 底层原理:afd.sys(Winsock 辅助驱动)维护全局 TCP 套接字计数器,限制用户态 Winsock 创建的 TCP Socket 句柄总数量。应用调用
socket()/WSASocket()新建 TCP 套接字时 AFD 做计数校验,达到阈值直接拒绝。和MaxUdpConnections成对,分别管控 TCP/UDP 套接字资源。 - 依赖文件:afd.sys、ws2_32.dll、registry.sys
- 依赖关系:系统启动阶段一次性读取加载,修改后必须重启生效;该约束属于上层套接字限制,优先级高于 tcpip.sys 的
TcpNumConnections;内核直接调用 tcpip.sys 的原生 TCP 流量不经过 AFD,不受该参数管控。 - 逻辑链路:业务程序 → ws2_32.dll Winsock API → IRP 下发 afd.sys → 校验当前 TCP Socket 总数<MaxTcpConnections
- ✅ 通过:分配 AFD 套接字控制块,继续下发 tcpip.sys 完成 TCB 分配
- ❌ 超限:直接返回
WSAENOBUFS(10055)
- 配套链:
MaxUdpConnections、NonPagedPoolQuota;连接统计Get-NetTCPConnection - 边界:监听 Socket 本身也是 1 个 Socket 句柄,可承载成千上万客户端连接,Socket 数量 ≠ TCP 四元组连接数量;仅管控用户态 Winsock 套接字。
2. DefaultSendWindow
注册表路径:HKLM\SYSTEM\CurrentControlSet\Services\AFD\Parameters\DefaultSendWindow
- 底层原理:AFD 套接字默认发送缓冲区大小(单位:字节)。新建套接字时自动分配该大小的内核发送缓冲区,用于暂存待下发协议栈的数据,减少频繁系统调用;应用未手动通过
SO_SNDBUF自定义缓冲区时生效。 - 依赖文件:afd.sys、ws2_32.dll、registry.sys、tcpip.sys
- 依赖关系:开机加载,重启生效;应用使用 setsockopt 自定义 SO_SNDBUF 会覆盖此默认值;缓冲区内存取自 AFD 占用的非分页池。
- 逻辑链路:创建 Socket → AFD 初始化套接字上下文,分配 DefaultSendWindow 大小内核缓冲区 → 应用 send/write 数据先写入该缓冲区 → afd 批量交付 tcpip.sys 发送。
- 配套链:
DefaultReceiveWindow、NonPagedPoolQuota、TCP 滑动窗口 - 边界:缓冲区越大,占用非分页内存越高,高并发场景容易耗尽 AFD 非分页配额;TCP 实际传输窗口还会受协议协商的滑动窗口限制,该参数只是内核套接字缓冲,不等于 TCP 窗口。
3. DefaultReceiveWindow
注册表路径:HKLM\SYSTEM\CurrentControlSet\Services\AFD\Parameters\DefaultReceiveWindow
- 底层原理:AFD 套接字默认接收缓冲区大小(单位:字节)。内核预先分配缓冲区存放网卡收到、还未被应用读取的数据;应用未手动配置
SO_RCVBUF时使用该值。UDP 场景下该缓冲区直接影响 UDP 报文积压能力。 - 依赖文件:afd.sys、ws2_32.dll、registry.sys、tcpip.sys、ndis.sys
- 依赖关系:开机加载,重启生效;应用自定义 SO_RCVBUF 优先级更高;内存消耗计入 AFD 非分页池配额。
- 逻辑链路:网卡报文送达 tcpip.sys → 转发 afd.sys → 存入 DefaultReceiveWindow 接收缓冲区 → 应用 recv 读取缓冲区数据。缓冲区满后新报文直接丢弃。
- 配套链:
DefaultSendWindow、MaxUdpConnections;UDP 丢包排查重点参数 - 边界:UDP 无流量控制,接收缓冲区不足极易出现UDP 静默丢包;TCP 场景缓冲区会配合协议滑动窗口做流量控制。
4. NonPagedPoolQuota
注册表路径:HKLM\SYSTEM\CurrentControlSet\Services\AFD\Parameters\NonPagedPoolQuota
- 底层原理:AFD 驱动能够使用的非分页内存总配额上限(单位:字节)。AFD 所有套接字控制块、收发缓冲区都从这块非分页池分配;达到配额上限后,新建 Socket、扩容缓冲区都会失败。是 AFD 侧最底层的资源硬限制。
- 依赖文件:afd.sys、registry.sys、ntoskrnl.exe(内核内存管理器)
- 依赖关系:开机加载,重启生效;该配额是 AFD 独立限额,不等于整机系统非分页池上限;整机非分页池耗尽时,即便 AFD 配额还有剩余依然分配失败。
- 逻辑链路:新建 Socket / 申请收发缓冲区 → afd 计算所需非分页内存 → 判断已使用内存<NonPagedPoolQuota
- ✅ 通过:分配内存
- ❌ 超限:创建套接字失败,返回
WSAENOBUFS(10055)/STATUS_INSUFFICIENT_RESOURCES
- 配套链:
MaxTcpConnections、MaxUdpConnections、DefaultSendWindow、DefaultReceiveWindow - 边界:配额设置过大,会抢占整机内核非分页资源,严重时触发系统蓝屏;高并发网关 / 日志 UDP 接收场景的隐形瓶颈。
✅ 统一完整 AFD 资源校验总链路
应用创建TCP/UDP Socket
↓
afd.sys 校验 MaxTcpConnections / MaxUdpConnections 套接字计数上限
↓
afd.sys 计算套接字控制块+收发缓冲区所需非分页内存
↓
校验 AFD NonPagedPoolQuota 是否充足
└─不足 → WSAENOBUFS(10055)
↓
分配DefaultSendWindow / DefaultReceiveWindow 默认缓冲区
↓
下发tcpip.sys协议栈继续处理
✅ UDP 套接字统计配套工具说明
# 查看本机所有UDP端点,可用于统计当前活跃UDP Socket数量
Get-NetUDPEndpoint
- 原理:查询 tcpip.sys 维护的 UDP 端点表,输出本地地址、端口、关联进程;可
(Get-NetUDPEndpoint).Count直接统计总量,用于对比MaxUdpConnections阈值。 - 边界:该命令统计的是已经绑定的 UDP 端点;部分临时未绑定的 socket 不会展示;内核 UDP 流量端点不纳入统计。
✅ 一键部署 PowerShell 脚本(AFD 全套参数)
$regAfd = "HKLM:\SYSTEM\CurrentControlSet\Services\AFD\Parameters"
if (-not (Test-Path $regAfd)) { New-Item -Path $regAfd -Force }
# TCP套接字上限
New-ItemProperty -Path $regAfd -Name "MaxTcpConnections" -Value 100000 -PropertyType DWord -Force
# 默认收发缓冲区(示例64KB)
New-ItemProperty -Path $regAfd -Name "DefaultSendWindow" -Value 65536 -PropertyType DWord -Force
New-ItemProperty -Path $regAfd -Name "DefaultReceiveWindow" -Value 65536 -PropertyType DWord -Force
# AFD非分页配额(示例256MB,单位字节)
New-ItemProperty -Path $regAfd -Name "NonPagedPoolQuota" -Value 268435456 -PropertyType DWord -Force
Write-Host "AFD注册表写入完成,必须重启服务器生效!"
✅ 整体边界汇总
- AFD 全系列注册表参数均在系统启动时加载,修改后重启才生效
- 资源约束优先级:
MaxTcpConnections/MaxUdpConnections→NonPagedPoolQuota→ 套接字缓冲区大小 DefaultSendWindow/DefaultReceiveWindow仅为默认值,程序 setsockopt 自定义缓冲区优先级更高- UDP 业务重点关注
DefaultReceiveWindow,缓冲区不足会出现无日志静默丢包 NonPagedPoolQuota是高并发场景最容易被忽略的底层瓶颈,超过配额直接新建 socket 失败
MaxUdpConnections(AFD 注册表项,Windows Server 2022 UDP 连接数)完整解构
注册表路径:
HKLM\SYSTEM\CurrentControlSet\Services\AFD\Parameters\MaxUdpConnections核心说明:AFD(Ancillary Function Driver for WinSock)是 Windows 套接字内核驱动,负责管理 UDP/TCP 套接字资源、连接控制,MaxUdpConnections用于全局限制系统同时存在的 UDP 套接字数量。
✅ 底层原理
- AFD 内核驱动(afd.sys)维护全局 UDP 套接字计数池,每创建一个 UDP Socket(
socket()、WSASocket()),AFD 内部计数器 + 1;关闭 Socket 后计数器释放。 MaxUdpConnections是该全局池的硬上限:当系统当前活跃 UDP 套接字数量达到该阈值时,新的 UDP Socket 创建直接失败,Winsock 返回 WSAENOBUFS(10055)。- 仅管控AFD 管理的用户态 UDP 套接字;内核自身协议栈、内核驱动直接创建的 UDP 流不受此参数限制。
- 默认行为:Windows Server 2022 默认不存在 MaxUdpConnections 注册表项,AFD 会使用系统内置默认上限(取决于内存、系统版本,默认通常足够常规业务,高并发 UDP 网关 / 日志接收 / 游戏服务器场景容易触顶)。
⚠️ 重要区分:
- MaxUdpConnections:UDP 套接字总数上限(socket 对象数量)
- 不等同于 UDP 四元组会话数量;单个 UDP Socket 可以收发大量不同四元组的报文(UDP 无连接特性)
- 和
MaxTcPConnections分开独立控制
✅ 依赖文件
| 文件 | 路径 | 核心作用 |
|---|---|---|
| afd.sys | C:\Windows\System32\drivers\afd.sys |
AFD Winsock 辅助驱动,读取 MaxUdpConnections 配置、维护 UDP 套接字计数器、上限校验 |
| tcpip.sys | C:\Windows\System32\drivers\tcpip.sys |
TCP/IP 协议栈,UDP 报文收发,和 AFD 协同工作 |
| registry.sys | 内核 | 注册表配置加载,系统启动时把 AFD 参数读入内核内存 |
| ws2_32.dll | System32\ws2_32.dll |
用户态 Winsock API 库,socket 创建调用,最终下发 IRP 至 afd.sys |
| afdproxy.sys | 部分版本配套 AFD 代理组件 | Winsock LSP / 分层套接字辅助 |
✅ 依赖关系
- 加载时机依赖:该注册表项仅系统启动阶段由 afd.sys 一次性读取;运行时修改注册表不实时生效,必须重启服务器。
- 内核组件依赖:必须启用 AFD 驱动,AFD 是 Winsock 必备组件,默认系统自带,不可直接卸载。
- 内存资源依赖:调大 MaxUdpConnections 会在内核分配更多套接字控制块内存;设置过大可能消耗非分页池内存,引发系统内存压力。
- 优先级约束:该全局上限 > 应用自身限制;即使程序无连接限制,到达 AFD 阈值依然创建失败。
- 与其他网络参数独立:不影响 TCP 连接数(
MaxTcpConnections)、UDP 接收缓冲区DefaultReceiveWindow等其他参数。
✅ 逻辑链路
系统开机 → registry.sys加载HKLM\SYSTEM\CurrentControlSet\Services\AFD\Parameters配置
→ afd.sys初始化,读取MaxUdpConnections值,写入内核全局UDP套接字上限变量
→ 应用调用ws2_32.dll → WSASocket创建UDP套接字
→ ws2_32下发IRP请求至afd.sys
→ afd.sys校验当前UDP套接字总数 < MaxUdpConnections
✅ 未达上限:分配AFD套接字控制块,创建成功,计数器+1
❌ 达到上限:直接拒绝,返回WSAENOBUFS(10055)
→ Socket关闭 → afd.sys回收资源,计数器-1
✅ 配套链
- 配套同类 AFD 注册表项
MaxTcpConnections:全局 TCP 套接字上限DefaultSendWindow/DefaultReceiveWindow:套接字默认缓冲区NonPagedPoolQuota:AFD 非分页池配额
- 查看当前 UDP 套接字数量工具
# 查看UDP端点(可统计当前活跃UDP socket) Get-NetUDPEndpoint - 错误排查:事件查看器(System 日志)、Winsock 错误码 10055
- 配套 PowerShell 脚本(注册表自动写入)
- 关联网络组件:Winsock LSP、WFP 筛选器、RRAS/NAT
✅ 边界(重点坑点)
- 不实时生效:修改注册表后必须重启操作系统,afd.sys 才会加载新值;热修改无效。
- 概念误区:UDP 是无连接协议,
MaxUdpConnections限制的是Socket 句柄数量,不是四元组 UDP 流数量;单个 UDP socket 可以承载成千上万不同对端报文。很多人误以为这个参数限制 UDP 并发流,这是典型误区。 - 非分页池上限约束:就算设置极大的 MaxUdpConnections,如果系统非分页池耗尽,依然无法新建套接字;该参数只是 AFD 层面上限,不是系统内存上限。
- 版本差异:旧版 Windows(2016 及更早)部分版本不识别
MaxUdpConnections,该注册表项在 Server2019/2022 才完整支持。 - 不作用于内核原生 UDP:内核驱动直接调用 tcpip.sys 收发 UDP(不经过 AFD)不受该参数管控。
- 和端口数量无关:不限制本地端口范围(本地端口由
DynamicPortRange控制)。 - 容器 / 网络虚拟化场景:如 Hyper-V、NAT 网关,虚拟网卡 UDP 资源还有独立层级限制,该参数只作用主机 AFD。
✅ 配套自动化脚本(Server2022 直接执行)
# 新建MaxUdpConnections,示例设置5000
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Services\AFD\Parameters"
if (-not (Test-Path $regPath)) { New-Item -Path $regPath -Force }
New-ItemProperty -Path $regPath -Name "MaxUdpConnections" -Value 5000 -PropertyType DWord -Force
Write-Host "注册表写入完成,需要重启服务器生效"
✅ 高频故障清单
- 已经设置 MaxUdpConnections,依然报 10055:未重启、非分页池耗尽、上层还有其他套接字限制
- Get-NetUDPEndpoint 数量远小于 MaxUdpConnections 但新建失败:存在内核级 UDP 不经过 AFD,或其他 WFP / 安全软件拦截
- 设置超大数值后服务器蓝屏 / 卡顿:内核非分页内存耗尽
合集目录
- Windows 非分页池监控 + 故障排查 SOP
- UDP 静默丢包专项排查手册
- WSAENOBUFS (10055) 全链路定位流程
- Winsock LSP 与 AFD 交互原理解构
- AFD + Tcpip 全套高并发调优汇总总表
适用平台:Windows Server 2019 / 2022,适用于 UDP 日志网关、TCP 长连接、短连接高并发服务
1、Windows 非分页池监控 + 故障排查 SOP
底层前置说明
非分页池(NonPaged Pool):内核内存,永远不会置换到页面文件;afd.sys 套接字控制块、收发缓冲区、tcpip.sys 的 TCB、NDIS 网卡驱动、WFP 过滤驱动全部消耗非分页池。 两个层级:整机系统非分页池 + AFD 独立 NonPagedPoolQuota 配额;AFD 配额够用,但整机非分页耗尽依然分配失败。
1.1 监控指标与采集命令
① PowerShell 实时监控
# 查看非分页池使用(任务管理器内核内存等价指标)
Get-CimInstance Win32_PerfFormattedData_Memory | Select NonPagedPoolBytes,NonPagedPoolAllocs,NonPagedPoolFrees
# 持续监控(每秒刷新)
while($true){
$m = Get-CimInstance Win32_PerfFormattedData_Memory
Write-Host "$(Get-Date) NonPagedPoolBytes: $($m.NonPagedPoolBytes)"
Start-Sleep 1
}
② 性能计数器(Perfmon)
\Memory\Non-Paged Pool Bytes、\Memory\Non-Paged Pool Allocations、\Memory\Non-Paged Pool Frees
告警阈值建议:非分页池持续超过物理内存 25%,或持续上涨不回落(内存泄漏)
③ 定位哪个驱动占用非分页池(关键!)
# 需要管理员权限,查看内核内存标签占用
poolmon
重点标签:Afd(AFD 套接字)、Tcp(tcpip.sys)、Ndis、Wfp、网卡厂商驱动
1.2 故障判定标准
- 新建 socket 失败、报错
WSAENOBUFS(10055)/STATUS_INSUFFICIENT_RESOURCES - poolmon 观察 Afd/Tcp 标签持续上涨,释放不回落 → 内存泄漏
- 整机 NonPagedPoolBytes 持续高位,新连接随机失败,业务无明确报错
- 严重时蓝屏(BUGCHECK: 0x000000D1 / 0x000000C5)
1.3 排查步骤 SOP
1)确认现象:是否新建 TCP/UDP 套接字失败,是否随机丢包、连接不稳定 2)采集性能指标:perfmon/poolmon,区分是整机非分页耗尽还是AFD 配额不足 3)定位内存占用模块:poolmon 确认是 Afd/tcpip/ 第三方 NDIS/WFP 驱动 4)核对注册表:AFD\Parameters\NonPagedPoolQuota、MaxTcpConnections/MaxUdpConnections、DefaultReceiveWindow 5)临时缓解方案:重启服务 / 重启服务器;降低单套接字缓冲区 DefaultReceiveWindow 6)根治:
- 业务侧:控制并发 socket 数量,不要无限制创建 socket
- 系统侧:合理设置 AFD NonPagedPoolQuota,不要盲目放大
- 驱动侧:升级网卡驱动、安全软件 / WFP 过滤驱动(很多第三方安全驱动存在非分页泄漏)
1.4 边界 & 坑
- 非分页池不能无限调大,受物理内存限制
- 虚拟机环境(Hyper-V/Azure)会额外限制内核内存
- 很多人只调 AFD 配额,忽略整机非分页池上限
2、UDP 静默丢包专项排查手册
前置原理
UDP 无连接、无 ACK、无重传;缓冲区满之后报文直接丢弃,上层应用无任何报错日志,即静默丢包。 核心链路:网卡 → NDIS → tcpip.sys → afd.sys → AFD DefaultReceiveWindow 缓冲区 → 业务 recv 读取
2.1 丢包分层定位顺序(从上到下)
业务应用缓冲区 → AFD 套接字接收缓冲区 (DefaultReceiveWindow) → Tcpip 协议栈 → 网卡 RingBuffer → 物理链路 / 交换机
2.2 排查工具
# 统计UDP端点数量,核对是否触达MaxUdpConnections
(Get-NetUDPEndpoint).Count
# 抓包:windump / wireshark 网卡侧抓包,区分是【网卡收到后内核丢弃】还是【根本没收到】
# Windows自带数据包捕获
netsh trace start capture=yes tracefile=c:\udp.etl
netsh trace stop
- 关键判断:网卡抓包能看到报文,但是应用收不到 → 内核协议栈 / AFD 缓冲区溢出丢包
- 网卡抓包本身就没有报文 → 网络链路、交换机、防火墙丢弃
2.3 SOP 排查流程
- 确认业务特征:高吞吐 UDP 日志 / 遥测 / 流媒体,突发流量?
- 网卡层抓包验证报文是否抵达本机
- 核对 AFD 参数:
DefaultReceiveWindow(UDP 核心参数)、MaxUdpConnections、NonPagedPoolQuota - 检查网卡高级属性:网卡接收缓冲区(Ring Buffer)是否足够
- 检查 WFP / 安全软件过滤驱动:部分防火墙会直接丢弃过载 UDP 报文
- 业务代码排查:是否 recv () 读取不及时,应用层缓冲区积压
- 验证修复:调大 DefaultReceiveWindow、增加 AFD 非分页配额、业务做流量削峰
2.4 典型坑
- TCP 调优思维套 UDP:TCP 有滑动窗口,UDP 没有,缓冲区满直接丢包
- 只看应用日志,内核层面丢包不会生成系统事件
- 大量短生命周期 UDP socket 快速创建销毁,快速耗尽 AFD 非分页池
2.5 推荐基线
高吞吐 UDP 网关:DefaultReceiveWindow = 65536 ~ 262144;配合充足 NonPagedPoolQuota
3、WSAENOBUFS (10055) 全链路定位流程
错误含义:WSAENOBUFS 10055 | 缓冲区空间不足,无法分配套接字资源 根本:AFD 分配套接字 / 缓冲区时资源不足,是高并发 Windows 服务器最高频报错
3.1 资源校验优先级(严格按顺序校验)
- AFD
MaxTcpConnections / MaxUdpConnections→ 是否达到 socket 句柄上限 - AFD
NonPagedPoolQuota→ AFD 自身非分页配额是否耗尽 - 整机系统非分页池是否耗尽(poolmon 验证)
- Tcpip 层:TcpNumConnections、TCB 资源是否耗尽
- 第三方组件:WFP 驱动、LSP、杀毒 / EDR 驱动抢占内核内存
- 业务代码:是否 socket 泄漏(创建后不 close)
3.2 定位 SOP
Step1:确认报错时机:新建 socket 时?收发数据时?
- 创建 socket 直接 10055:大概率 AFD 计数 / AFD 非分页 / 整机非分页耗尽
- 收发过程中偶尔 10055:缓冲区不足、突发流量抢占内存
Step2:采集当前 socket 数量
# TCP socket统计
(Get-NetTCPConnection).Count
# UDP socket统计
(Get-NetUDPEndpoint).Count
Step3:poolmon 核查非分页池占用,确认 Afd 标签增长 Step4:核对 AFD 注册表四项:MaxTcp/MaxUdp、DefaultSend/ReceiveWindow、NonPagedPoolQuota Step5:排查是否存在 Socket 泄漏:进程句柄持续上涨不释放 Step6:临时验证:重启服务 / 整机重启,如果恢复,基本确认是内核内存资源耗尽
3.3 临时缓解 & 根治方案
临时:降低并发、重启释放内核内存 根治:
- 合理配置 AFD 参数,不要盲目超大缓冲区
- 业务代码及时关闭闲置 Socket,杜绝句柄泄漏
- 升级网卡、安全驱动(驱动内存泄漏是高频隐形原因)
3.4 易混淆区分
- WSAENOBUFS (10055):AFD/Winsock 资源不足
- WSAECONNREFUSED:端口未监听
- WSAETIMEDOUT:网络不通超时
4、Winsock LSP 与 AFD 交互原理解构
4.1 基础定义
- LSP(Layered Service Provider,分层服务提供程序):Winsock2 扩展机制,可以拦截所有应用 Winsock 调用(socket/connect/send/recv),早期用于代理、防火墙、流量审计。Win10/Server2016 之后微软推荐使用 WFP 替代 LSP,但存量软件仍然大量使用 LSP。
- AFD.sys:内核态 Winsock 辅助驱动,LSP 属于用户态中间层,LSP 本身不直接处理报文,最终仍然下发 IRP 调用 AFD。
4.2 完整调用链路
应用程序 → ws2_32.dll → LSP分层DLL(自定义过滤逻辑) → ws2_32基础提供者 → IRP → afd.sys → tcpip.sys → NDIS → 网卡
LSP 可以拦截、修改、拒绝 socket 创建、收发数据;可以篡改 IP / 端口、拦截报文。
4.3 依赖文件
- ws2_32.dll:Winsock2 基础库
- LSP 自定义 dll(第三方安全 / 代理软件注入)
- afd.sys、tcpip.sys
- 注册表路径:
HKLM\SYSTEM\CurrentControlSet\Services\Winsock2\Parameters\Protocol_Catalog9存储 LSP 目录
4.4 依赖关系
- LSP 是全局钩子,所有进程 Winsock 调用都会经过注册的 LSP
- LSP 本身不维护 TCB、不占用 AFD 计数,但 LSP 异常会直接阻断 socket 调用,抛出 10055 等错误
- LSP 必须正确转发底层 Winsock 调用,如果 LSP 内存泄漏,会连带大量 socket 资源无法释放
4.5 边界 & 风险
- LSP 极易引发 WSAENOBUFS (10055)、网络随机异常,老旧安全软件、VPN 客户端是重灾区
- LSP 损坏会导致整机网络异常,无法联网
- 新版 Windows 微软逐步弃用 LSP,优先 WFP(Windows Filtering Platform)
- 排查命令:查看已注册 LSP
netsh winsock show catalog
# 重置winsock(修复损坏LSP,高危,业务窗口执行)
netsh winsock reset
4.6 和 WFP 区别总结
- LSP:用户态,拦截 Winsock API,老技术,兼容性坑多
- WFP:内核态,直接在 tcpip/NDIS 层拦截报文,现代推荐方案
5、AFD + Tcpip 全套高并发调优汇总总表
✅ = 生效;🔄 = 需要重启;⚙ = Set-NetTCPSetting 可热配置;⚠ = 风险项
| 分类 | 注册表参数 | 路径 | 作用 | 推荐基线 (Server2022 高并发) | 是否重启 | 风险说明 |
|---|---|---|---|---|---|---|
| AFD-TCP 套接字上限 | MaxTcpConnections | AFD\Parameters | 用户态 TCP Socket 句柄上限 | 100000 | 🔄是 | 仅管控 Winsock socket,不等于连接数 |
| AFD-UDP 套接字上限 | MaxUdpConnections | AFD\Parameters | 用户态 UDP Socket 句柄上限 | 100000 | 🔄是 | UDP 网关重点参数 |
| AFD 默认发送缓冲区 | DefaultSendWindow | AFD\Parameters | Socket 默认发送缓冲 | 65536 | 🔄是 | 业务 setsockopt 会覆盖 |
| AFD 默认接收缓冲区 | DefaultReceiveWindow | AFD\Parameters | Socket 默认接收缓冲(UDP 丢包核心) | 131072 | 🔄是 | 过大会快速消耗非分页池 |
| AFD 非分页配额 | NonPagedPoolQuota | AFD\Parameters | AFD 可使用非分页总上限 | 268435456(256MB) | 🔄是 | 设置过大挤压整机内核内存 |
| Tcpip-TCB 总数 | TcpNumConnections | Tcpip\Parameters | 整机 TCP 控制块上限 | 16000000 | 🔄是 | 默认值很大,一般不瓶颈 |
| Tcpip 动态端口 | MaxUserPort | Tcpip\Parameters | 客户端出站临时端口上限 | 65534 | 🔄是 | 大量短连接出站必调 |
| Tcpip TIME_WAIT 回收 | TcpTimedWaitDelay | Tcpip\Parameters | TIME_WAIT 时长 (秒) | 30 | 🔄是 | 低于 30 易出现报文冲突 |
| Tcpip 空闲 TCB 池 | MaxFreeTcbs | Tcpip\Parameters | 预分配空闲 TCB 缓存 | 200000 | 🔄是 | 加速新建连接,消耗非分页 |
| Tcpip 哈希表 | MaxHashTableSize | Tcpip\Parameters | TCP 四元组哈希表大小 (2 的幂) | 65536 | 🔄是 | 不限制连接,高并发降 CPU |
配套 PowerShell 一键部署脚本(汇总完整版)
# AFD 参数
$regAfd = "HKLM:\SYSTEM\CurrentControlSet\Services\AFD\Parameters"
if (-not (Test-Path $regAfd)) { New-Item -Path $regAfd -Force }
New-ItemProperty -Path $regAfd -Name "MaxTcpConnections" -Value 100000 -PropertyType DWord -Force
New-ItemProperty -Path $regAfd -Name "MaxUdpConnections" -Value 100000 -PropertyType DWord -Force
New-ItemProperty -Path $regAfd -Name "DefaultSendWindow" -Value 65536 -PropertyType DWord -Force
New-ItemProperty -Path $regAfd -Name "DefaultReceiveWindow" -Value 131072 -PropertyType DWord -Force
New-ItemProperty -Path $regAfd -Name "NonPagedPoolQuota" -Value 268435456 -PropertyType DWord -Force
# Tcpip 参数
$regTcpip = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
New-ItemProperty -Path $regTcpip -Name "TcpNumConnections" -Value 16000000 -PropertyType DWord -Force
New-ItemProperty -Path $regTcpip -Name "MaxUserPort" -Value 65534 -PropertyType DWord -Force
New-ItemProperty -Path $regTcpip -Name "TcpTimedWaitDelay" -Value 30 -PropertyType DWord -Force
New-ItemProperty -Path $regTcpip -Name "MaxFreeTcbs" -Value 200000 -PropertyType DWord -Force
New-ItemProperty -Path $regTcpip -Name "MaxHashTableSize" -Value 65536 -PropertyType DWord -Force
Write-Host "✅ AFD+Tcpip高并发参数写入完成!必须重启服务器生效!"
整体调优优先级总结
- 优先排查业务代码 socket 泄漏(最常见根本问题)
- 优先确认整机非分页池是否充足
- 再调整 AFD 套接字数量、缓冲区、NonPagedPoolQuota
- 短连接业务重点优化
MaxUserPort + TcpTimedWaitDelay - UDP 业务核心:
DefaultReceiveWindow - 高并发大量 TCP 连接:
MaxHashTableSize降低 CPU 开销
合集目录
- Windows 非分页池原理 + 监控 SOP
- TIME_WAIT 高问题专项排查 SOP
- WSAENOBUFS (10055) 全链路排查手册
- TCP 半连接(SYN 队列)参数解构
- AFD 全套注册表参数汇总表
适配系统:Windows Server 2019 / 2022,适用于 TCP 高并发服务、UDP 日志网关场景
1、Windows 非分页池原理 + 监控 SOP
1.1 底层原理
非分页池(Non-Paged Pool)是内核常驻内存区域,这部分内存不会被交换到页面文件,任何时刻都可以直接被内核驱动访问。
- 占用主体:afd.sys 套接字控制块、套接字收发缓冲区、tcpip.sys 的 TCB、SYN 队列、NDIS 网卡驱动、WFP/EDR 过滤驱动
- 两级约束:整机系统非分页池上限 + AFD 独立 NonPagedPoolQuota 配额
即使 AFD 配额还有剩余,如果整机非分页池耗尽,依然无法分配内存,新建 Socket / 连接失败
- 内存泄漏典型表现:NonPagedPoolBytes 持续上涨,重启后恢复
1.2 监控指标与采集工具
① 性能计数器(Perfmon 推荐长期监控)
\Memory\Non-Paged Pool Bytes 【核心指标】 \Memory\Non-Paged Pool Allocations \Memory\Non-Paged Pool Frees 告警阈值:非分页池持续占用超过物理内存 25%;持续只增不减判定内存泄漏
② PowerShell 实时采集
# 查询非分页池占用
Get-CimInstance Win32_PerfFormattedData_Memory | Select NonPagedPoolBytes,NonPagedPoolAllocs,NonPagedPoolFrees
# 持续监控(每秒刷新)
while($true){
$info = Get-CimInstance Win32_PerfFormattedData_Memory
Write-Host "$(Get-Date) NonPagedPoolBytes : $($info.NonPagedPoolBytes)"
Start-Sleep 1
}
③ poolmon(定位是哪个内核驱动消耗内存,管理员 CMD 执行)
poolmon
重点标签:Afd(AFD 套接字)、Tcp(tcpip 协议栈)、Ndis网卡驱动、Wfp过滤平台
1.3 标准化排查 SOP
- 现象确认:是否新建 TCP/UDP 套接字失败、随机丢包、业务间断报错
- 指标采集:perfmon 记录非分页池趋势,poolmon 定位内存占用模块
- 分层判定
- poolmon
Afd持续上涨 → AFD 套接字 / 缓冲区耗尽,核对 AFD 注册表 - poolmon
Tcp持续上涨 → TCB 大量占用或 tcpip 内存泄漏 Ndis/Wfp持续上涨 → 网卡驱动 / 安全 EDR 驱动内存泄漏
- poolmon
- 临时缓解:重启业务服务或整机,快速释放内核内存
- 根治方案
- 业务侧:及时关闭闲置 Socket,杜绝句柄泄漏
- 系统侧:合理配置
NonPagedPoolQuota,不要盲目放大套接字缓冲区 - 驱动侧:升级网卡、安全软件驱动
1.4 边界坑点
- 虚拟机(Hyper-V/Azure)存在内核内存硬限制,物理机基线不直接适用
- 只调 AFD 配额,忽略整机非分页池上限,问题依旧复现
- 非分页池耗尽严重时触发蓝屏 0xD1 / 0xC5
2、TIME_WAIT 高问题专项排查 SOP
2.1 底层原理
TIME_WAIT 是 TCP 四次挥手后主动关闭方的状态,默认 240s。核心目的:
- 保证对端收到 FIN 报文,正常释放资源
- 防止网络延迟的重复旧报文干扰新建同四元组连接
大量 TIME_WAIT 几乎全部出现在客户端角色(主动发起连接、短连接),入站监听服务一般不会大量产生 TIME_WAIT。 大量 TIME_WAIT 会快速耗尽本机动态端口池,无法新建出站连接。
2.2 关键注册表参数
路径:HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
TcpTimedWaitDelay:TIME_WAIT 超时时间,单位秒,默认 240,推荐 30(不要低于 30)MaxUserPort:出站动态端口上限,默认 49152~65535TcpMaxDataRetransmissions:报文重传次数(辅助参数)
2.3 SOP 排查流程
- 确认现象:新建出站连接失败,报错无法连接;
Get-NetTCPConnection大量 TimeWait 状态
# 统计TIME_WAIT数量
(Get-NetTCPConnection | Where-Object State -eq TimeWait).Count
# 查看TIME_WAIT明细
Get-NetTCPConnection | Where-Object State -eq TimeWait | Select LocalAddress,LocalPort,RemoteAddress,State
- 判断角色:本机是客户端(主动建连)还是服务端
- 客户端:典型瓶颈
MaxUserPort + TcpTimedWaitDelay - 服务端大量 TIME_WAIT:业务主动 close 连接,需要业务优化长连接复用
- 客户端:典型瓶颈
- 核对动态端口范围:
Get-NetTCPSetting | Select DynamicPortRangeStart,DynamicPortRangeNumberOfPorts
- 抓包验证:确认是业务大量短连接快速建连释放
- 优化落地
- 系统:调小
TcpTimedWaitDelay=30、调大MaxUserPort=65534 - 业务优先优化:连接池复用、长连接,从根源减少短连接
- 系统:调小
- 验证优化效果:持续观测 TIME_WAIT 数量是否回落
2.4 风险边界
TcpTimedWaitDelay <30:网络延迟场景下容易出现旧报文污染新连接,引发数据错乱。
Set-NetTCPSetting 可热生效该参数,无需重启(新版 Win Server 支持)
3、WSAENOBUFS (10055) 全链路排查手册
3.1 错误释义
WSAENOBUFS 10055:缓冲区资源不足,无法分配套接字资源 本质:AFD 在创建 Socket / 分配内核缓冲区时内核资源不足,是 Windows 高并发网络最经典报错。
3.2 资源校验优先级(严格顺序排查)
- AFD
MaxTcpConnections / MaxUdpConnections→ Socket 句柄是否达到上限 - AFD
NonPagedPoolQuota→ AFD 专属非分页内存是否耗尽 - 整机系统非分页池是否耗尽(poolmon 验证)
- Tcpip
TcpNumConnections→ 整机 TCB 是否耗尽 - 第三方组件:WFP 过滤驱动、LSP、EDR / 杀毒驱动抢占内核内存
- 业务代码:Socket 泄漏(创建后不 close,句柄持续累积)
3.3 分步排查流程
Step1:确认报错时机
- 创建 Socket 直接抛出 10055:大概率 AFD 计数 / 非分页池耗尽
- 收发数据过程随机抛出 10055:套接字缓冲区不足、突发流量冲击 Step2:统计当前 Socket 数量
# TCP socket统计
(Get-NetTCPConnection).Count
# UDP socket统计
(Get-NetUDPEndpoint).Count
Step3:poolmon 核查 Afd/Tcp 标签内存增长情况 Step4:核对 AFD 全套注册表参数 Step5:检查 Winsock 目录是否存在异常 LSP
netsh winsock show catalog
Step6:临时验证:重启服务 / 整机,如果恢复 → 确认内核资源耗尽类问题
3.4 解决方案
临时缓解:降低并发量,重启释放内核内存 根治:合理配置 AFD 参数、业务及时回收 Socket、升级异常驱动
3.5 易混淆错误区分
| 错误码 | 含义 |
|---|---|
| WSAENOBUFS(10055) | AFD/Winsock 内核资源不足 |
| WSAECONNREFUSED | 远端端口未监听 |
| WSAETIMEDOUT | 网络链路超时 |
4、TCP 半连接(SYN 队列)参数解构
半连接:收到客户端 SYN,回复 SYN+ACK,等待客户端 ACK 完成三次握手,该状态连接存放在 SYN 队列。SYN 队列溢出会直接丢弃新客户端 SYN 包,客户端表现为连接超时、间歇性无法接入。
4.1 核心注册表路径
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
| 参数名 | 作用 | 说明 |
|---|---|---|
| TcpMaxSynBacklog | 单监听端口 SYN 队列最大长度 | 限制单个 Listener 的半连接上限 |
| SynAttackProtect | SYN 洪水防护开关 | 2 = 开启防护,会动态缩减 SYN 队列、启用 Cookie |
| TcpMaxConnectResponseRetransmissions | SYN+ACK 重传次数 | 重试多次无 ACK 直接清理半连接 |
4.2 底层逻辑链路
客户端 SYN → tcpip.sys → 查找监听 Socket → 写入该端口 SYN 队列 → 回复 SYN+ACK ✅ 收到 ACK → 移出 SYN 队列,创建 TCB,连接成功 ❌ 队列已满 → 直接丢弃 SYN 报文,客户端连接超时 ❌ 长时间无 ACK → 超时清理半连接
4.3 推荐基线(高并发入站服务)
TcpMaxSynBacklog:1000~4000,根据业务并发接入峰值调整SynAttackProtect=2(默认开启,抵御 SYN 洪水)
⚠️ SynAttackProtect 开启后,系统会自动弱化 SYN 队列,极端场景下即使调大 TcpMaxSynBacklog 也不生效
4.4 排查命令
# 查看当前半连接(SYN_RCVD)数量
Get-NetTCPConnection | Where-Object State -eq SynReceived
4.5 边界坑
- SynAttackProtect 开启时,TcpMaxSynBacklog 不会完全生效
- SYN 队列占用非分页池,队列设置过大加剧内核内存压力
- 负载均衡场景,前端 LB 和后端服务器 SYN 队列需要配套调优
一键写入脚本
$regTcpip = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
New-ItemProperty -Path $regTcpip -Name "TcpMaxSynBacklog" -Value 2000 -PropertyType DWord -Force
New-ItemProperty -Path $regTcpip -Name "SynAttackProtect" -Value 2 -PropertyType DWord -Force
New-ItemProperty -Path $regTcpip -Name "TcpMaxConnectResponseRetransmissions" -Value 2 -PropertyType DWord -Force
5、AFD 全套注册表参数汇总表
统一前缀:HKLM\SYSTEM\CurrentControlSet\Services\AFD\Parameters
🔄 修改后必须重启服务器;✅ 高并发推荐值
| 参数名称 | 功能说明 | 推荐基线 | 风险提示 |
|---|---|---|---|
| MaxTcpConnections | 用户态 TCP Socket 句柄全局上限 | 100000 | Socket 句柄 ≠ TCP 连接数,一个监听 socket 承载大量连接 |
| MaxUdpConnections | 用户态 UDP Socket 句柄全局上限 | 100000 | UDP 网关核心参数,超出后新建 UDP socket 报 10055 |
| DefaultSendWindow | Socket 默认发送缓冲区(字节) | 65536 | 程序 setsockopt 设置 SO_SNDBUF 会覆盖该默认值 |
| DefaultReceiveWindow | Socket 默认接收缓冲区(字节) | 131072 | UDP 重点参数,过小直接静默丢包;过大会快速消耗非分页 |
| NonPagedPoolQuota | AFD 可占用非分页内存总配额(字节) | 268435456(256MB) | 配额过大挤压整机内核内存,过小直接分配失败 |
AFD 一键部署脚本
$regAfd = "HKLM:\SYSTEM\CurrentControlSet\Services\AFD\Parameters"
if (-not (Test-Path $regAfd)) { New-Item -Path $regAfd -Force }
New-ItemProperty -Path $regAfd -Name "MaxTcpConnections" -Value 100000 -PropertyType DWord -Force
New-ItemProperty -Path $regAfd -Name "MaxUdpConnections" -Value 100000 -PropertyType DWord -Force
New-ItemProperty -Path $regAfd -Name "DefaultSendWindow" -Value 65536 -PropertyType DWord -Force
New-ItemProperty -Path $regAfd -Name "DefaultReceiveWindow" -Value 131072 -PropertyType DWord -Force
New-ItemProperty -Path $regAfd -Name "NonPagedPoolQuota" -Value 268435456 -PropertyType DWord -Force
Write-Host "AFD参数写入完成,需要重启生效!"
合集目录
- WFP Windows 过滤平台底层解构
- Windows IOCP 原理与高并发 Socket 模型
- 整套 Windows 网络压测验证脚本
- Windows 服务器网络基线巡检清单
- TCB、四元组哈希表 MaxHashTableSize 深度拆解
适配系统:Windows Server 2019 / 2022,配套前面 AFD/TCPIP 高并发体系
1、WFP Windows 过滤平台底层解构
1.1 基础定义
WFP(Windows Filtering Platform,Windows 过滤平台)是微软现代内核态报文过滤框架,用来替代老旧 LSP。杀毒软件、EDR、防火墙、流量审计、NAT、端口转发底层基本都基于 WFP。 核心特点:在内核协议栈不同层挂载过滤回调,直接拦截 / 修改 / 丢弃报文,分为用户态管理 API + 内核过滤引擎(fwpk.sys)。
1.2 核心依赖文件
fwpk.sys:WFP 内核引擎主体驱动tcpip.sys:和 WFP 深度集成,提供报文注入点ndis.sys:链路层过滤入口fwpuclnt.dll:用户态 WFP 管理 API 库bfe.dll/bfe.sys:Base Filtering Engine(基础过滤引擎服务)
服务名称:
BFE(Base Filtering Engine),WFP 正常工作依赖此服务,不能随意禁用
1.3 分层过滤链路(过滤层由下至上)
网卡 → NDIS层(FWPM_LAYER_INBOUND_MAC/OUTBOUND_MAC)
→ IP层(FWPM_LAYER_INBOUND_IPPACKET_V4/V6)
→ 传输层(FWPM_LAYER_INBOUND_TRANSPORT_V4/V6,TCP/UDP)
→ AFD/Winsock流层(FWPM_LAYER_STREAM_V4/V6)
→ 应用程序
两种模式:
- 注入拦截:直接丢弃 / 修改报文(防火墙、入侵检测)
- 流检测:跟踪 TCP 流状态,识别完整连接(EDR 审计)
1.4 核心对象模型
- Filter(过滤器):匹配条件 + 动作(允许 / 阻止 / 标注 / 重定向)
- Layer(过滤层):报文拦截的位置
- SubLayer(子层):同一层多个过滤器执行优先级排序
- Callout(回调):自定义内核处理函数,第三方安全软件核心扩展点
1.5 完整逻辑链路
- BFE 服务启动,加载注册的 Callout 驱动
- 第三方安全 / 防火墙驱动向 WFP 注册过滤器、回调函数
- 报文流经 tcpip/ndis 对应过滤层
- WFP 按子层优先级依次匹配过滤器
- 命中 Callout → 执行自定义内核逻辑(丢包、篡改、日志)
- 放行报文继续向上交付 AFD,最终到应用
1.6 依赖关系 & 和 LSP 对比
| 项目 | WFP | LSP |
|---|---|---|
| 运行态 | 内核态 | 用户态 |
| 拦截位置 | NDIS/IP/TCP/Stream 多层 | Winsock API 层 |
| 稳定性 | 高,微软主推 | 极易损坏,容易 10055、网络异常 |
| 流感知 | 支持 TCP 流跟踪 | 仅 API 拦截,无内核流信息 |
1.7 边界 & 坑
- WFP Callout 驱动大量处理报文时,消耗大量非分页池,是 10055、内存泄漏高频诱因
- BFE 服务异常会直接导致所有 WFP 规则失效、防火墙异常
- 大量复杂 WFP 规则会拉高内核 CPU,高并发网关重点排查项
- 排查命令
# 查看WFP过滤器
netsh wfp show filters
# 查看活跃子层
netsh wfp show sublayers
# 重启BFE服务
Restart-Service BFE
2、Windows IOCP 原理与高并发 Socket 模型
2.1 IOCP 定义
IOCP(I/O Completion Port,I/O 完成端口),Windows 平台最高性能异步 Socket 模型,适合百万级 TCP 长连接、UDP 高吞吐网关。
适用场景:日志接收网关、IM 服务、反向代理;不适合极低并发简单业务。
2.2 底层原理
- 创建 IOCP 内核对象,绑定 Socket 句柄到 IOCP
- 投递异步 IO(WSARecv / WSASend),线程不阻塞等待
- 内核 AFD/tcpip 完成 IO 后,将完成事件 + 数据压入 IOCP 队列
- 少量工作线程循环从 IOCP 队列取出完成事件处理业务逻辑
核心优势:少量线程处理海量连接,避免多线程一连接一线程的上下文切换爆炸。
2.3 依赖文件
ntoskrnl.exe(IOCP 内核实现)、afd.sys、ws2_32.dll
2.4 完整调用链路
程序创建Socket → 创建IOCP → 将Socket绑定至IOCP
→ 投递WSARecv异步接收缓冲区(交给AFD内核)
网卡报文到达 → tcpip → afd.sys填充缓冲区 → 将完成包入IOCP队列
→ 工作线程GetQueuedCompletionStatus取出事件,执行业务处理
→ 再次投递WSARecv,循环复用缓冲区
2.5 Windows 主流 Socket 模型横向对比
| 模型 | 并发上限 | 适用场景 | 缺点 |
|---|---|---|---|
| Select | 千级 | 简易工具、低并发 | fd_set 上限,性能差 |
| WSAEventSelect | 万级 | 中小型服务 | 事件句柄瓶颈 |
| WSAAsyncSelect | 千级 | GUI 程序 | 消息队列瓶颈 |
| IOCP | 百万级 | 网关、长连接集群 | 开发复杂,内存管理要求高 |
2.6 边界坑点
- IOCP 本身不限制连接数,瓶颈依然是:AFD 套接字上限、非分页池、TCB 数量
- 缓冲区管理不当极易造成非分页泄漏,长期运行出现 10055
- 投递过多未完成 IO 请求会触发内核资源限制
- 虚拟机环境 IOCP 性能衰减明显
极简 IOCP 伪代码框架(C 风格示意)
CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
CreateSocket();
CreateIoCompletionPort((HANDLE)sock, hIOCP, key, 0);
WSARecv(sock, &buf, 1, &flags, &overlap, NULL); // 投递异步接收
while(TRUE){
GetQueuedCompletionStatus(hIOCP, &bytes, &key, &overlap, INFINITE);
// 业务处理
WSARecv(sock, &buf, 1, &flags, &overlap, NULL); // 复用buffer继续接收
}
3、整套 Windows 网络压测验证脚本
用途:验证 AFD/Tcpip 调优是否生效、复现 TIME_WAIT、10055、SYN 队列溢出 前置:PowerShell 管理员权限;分为【短连接压测(TIME_WAIT)】、【长连接压测(IOCP/TCB)】、【UDP 压测(UDP 静默丢包)】 ⚠️ 禁止直接在生产业务机高并发压测,优先测试机!
3.1 短连接 TCP 压测脚本(快速生成 TIME_WAIT)
<#
用途:大量短连接快速建连关闭,用于验证MaxUserPort、TcpTimedWaitDelay
#>
$targetIp = "127.0.0.1"
$targetPort = 8080
$threadCount = 200
$loopPerThread = 500
$script:globalStop = $false
$jobBlock = {
param($ip,$port,$loop)
for($i=0;$i -lt $loop;$i++){
if($script:globalStop){break}
try{
$tcpClient = New-Object System.Net.Sockets.TCPClient
$tcpClient.Connect($ip,$port)
$tcpClient.Close()
$tcpClient.Dispose()
}catch{
Write-Host "连接失败 $_"
}
Start-Sleep -Milliseconds 2
}
}
$jobs = @()
for($t=0;$t -lt $threadCount;$t++){
$jobs += Start-Job -ScriptBlock $jobBlock -ArgumentList $targetIp,$targetPort,$loopPerThread
}
Write-Host "压测运行中,监控TIME_WAIT数量:(Get-NetTCPConnection|?{$_.State -eq 'TimeWait'}).Count"
Wait-Job $jobs
3.2 UDP 压测脚本(验证 UDP 静默丢包、DefaultReceiveWindow)
$targetIp = "127.0.0.1"
$targetPort = 9999
$sendCount = 10000
$udp = New-Object System.Net.Sockets.UdpClient
$sendBuf = [byte[]]::CreateInstance([byte],1024)
for($i=0;$i -lt $sendCount;$i++){
$udp.Send($sendBuf,$sendBuf.Length,$targetIp,$targetPort)
}
$udp.Close()
Write-Host "UDP报文发送完成,核查接收端是否丢包"
3.3 实时监控脚本(压测配套)
while($true){
$tcpTotal = (Get-NetTCPConnection).Count
$timeWait = (Get-NetTCPConnection | Where-Object State -eq TimeWait).Count
$synRcvd = (Get-NetTCPConnection | Where-Object State -eq SynReceived).Count
$udpEp = (Get-NetUDPEndpoint).Count
$mem = Get-CimInstance Win32_PerfFormattedData_Memory
Write-Host "$(Get-Date) TCP总:$tcpTotal TIME_WAIT:$timeWait SYN_RCVD:$synRcvd UDP:$udpEp NonPaged:$($mem.NonPagedPoolBytes)"
Start-Sleep 1
}
3.4 第三方压测工具补充
NTttcp:微软官方 Windows TCP 性能压测工具(经典,适合 TCB 吞吐验证)Packet Sender:图形化 UDP/TCP 测试hping3(Windows版):SYN 洪水测试,验证 SYN 队列与 SynAttackProtect
4、Windows 服务器网络基线巡检清单
适用:Windows Server 2019/2022 业务服务器上线 / 定期巡检,输出巡检报告
✅ 一、内核网络注册表基线巡检
| 检查项 | 预期基线 |
|---|---|
| AFD MaxTcpConnections | 根据业务并发配置,不为极小值 |
| AFD MaxUdpConnections | UDP 网关需合理配置 |
| AFD NonPagedPoolQuota | 不盲目超大,不缺失 |
| AFD DefaultReceiveWindow | UDP 业务≥65536 |
| Tcpip TcpNumConnections | 默认 0x00FFFFFE 或合理大值 |
| Tcpip MaxUserPort | 65534 |
| Tcpip TcpTimedWaitDelay | 30~240 |
| Tcpip MaxHashTableSize | 2 的幂,高并发≥65536 |
| Tcpip TcpMaxSynBacklog | 入站服务≥1000 |
| SynAttackProtect | 2 |
✅ 二、系统服务巡检
- BFE(WFP 基础过滤引擎):运行、自动
- WinNat、Wlansvc(按需)
- 第三方 EDR / 防火墙驱动状态
✅ 三、内存 & 内核资源巡检
- NonPagedPoolBytes 持续不超过物理内存 25%,无持续上涨
- poolmon 无 Afd/Tcp/WFP 内存持续泄漏
- 无 0xD1/0xC5 蓝屏历史
✅ 四、网卡与 NDIS 巡检
- 网卡驱动为稳定正式版,非测试版
- 网卡高级属性:接收缓冲区、RSS、VMQ(虚拟机)开启合理
- 网卡无持续丢包、错包
Get-NetAdapterStatistics
✅ 五、连接与状态巡检
- 无异常大量 TIME_WAIT(短连接业务除外)
- SYN_RCVD 数量平稳,无持续堆积
- Socket 数量未触达 AFD 上限
- 无持续 WSAENOBUFS 报错日志
✅ 六、安全组件巡检
- Winsock 目录无异常老旧 LSP
netsh winsock show catalog
- WFP 过滤器无冗余大量自定义 Callout 规则
✅ 七、输出巡检一键脚本
Write-Host "===== 网络注册表 ====="
$regAfd = "HKLM:\SYSTEM\CurrentControlSet\Services\AFD\Parameters"
$regTcpip = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
Get-ItemProperty $regAfd -ErrorAction SilentlyContinue
Get-ItemProperty $regTcpip -ErrorAction SilentlyContinue
Write-Host "`n===== 连接统计 ====="
Write-Host "TCP总数: $((Get-NetTCPConnection).Count)"
Write-Host "TIME_WAIT: $((Get-NetTCPConnection|?{$_.State -eq 'TimeWait'}).Count)"
Write-Host "SYN_RCVD: $((Get-NetTCPConnection|?{$_.State -eq 'SynReceived'}).Count)"
Write-Host "UDP端点: $((Get-NetUDPEndpoint).Count)"
Write-Host "`n===== 网卡统计 ====="
Get-NetAdapterStatistics
Write-Host "`n===== BFE服务 ====="
Get-Service BFE
5、TCB、四元组哈希表 MaxHashTableSize 深度拆解
5.1 TCB(TCP Control Block,TCP 控制块)
- 底层定义:tcpip.sys 内核中,每一条已经完成三次握手的 TCP 连接唯一对应的内核数据结构。存储四元组(源 IP、源端口、目的 IP、目的端口)、序列号、ACK、滑动窗口、重传定时器、状态机(ESTABLISHED/TIME_WAIT 等)。
- 占用资源:非分页池内存,是高并发 TCP 场景最主要内存消耗项
- 管控参数:
TcpNumConnections= 整机最大 TCB 总数上限 - 生命周期:三次握手成功 → 创建 TCB;四次挥手完成 + TIME_WAIT 超时 → 释放 TCB,内存归还内核;空闲 TCB 会存入
MaxFreeTcbs空闲缓存池加速复用
5.2 MaxFreeTcbs
预分配空闲 TCB 缓存池上限。新建连接优先直接从池子拿 TCB,省去实时申请非分页内存开销,提升新建连接性能;空闲 TCB 超过该阈值,内核主动释放内存。
5.3 MaxHashTableSize 底层原理
注册表路径:
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxHashTableSize✅ 必须是 2 的整数次幂(512/1024/2048/4096/8192/65536)
- tcpip 内核维护一张全局 TCB 哈希表,key = TCP 四元组哈希值
- 报文到达网卡,内核计算四元组 hash,直接索引哈希表快速找到对应 TCB
- 哈希表越小 → 哈希冲突越多 → 需要链表遍历查找 TCB → CPU 急剧升高
- 哈希表足够大时,几乎 O (1) 直接命中 TCB,高并发下显著降低内核 CPU
5.4 完整链路
TCP报文入栈 → 提取四元组 → 计算hash
→ 查询MaxHashTableSize定义的哈希桶数组
→ 桶内遍历匹配TCB
→ 更新序列号、窗口、定时器等TCB字段
5.5 依赖关系
- 仅影响TCP 已建立连接的查找性能,不限制最大连接数量(很多人误区)
- 和 TcpNumConnections、MaxFreeTcbs 配套使用
- 修改后重启生效
- 适合调优场景:上万长连接、网关、代理服务器,内核 CPU 持续偏高
5.6 边界坑
- 非 2 的幂配置会被内核自动向下取最近 2 次幂,配置不生效
- 设置极大哈希表会预占用少量内核内存,一般可忽略
- 短连接场景、连接数量很少时,调这个参数几乎无收益
一键配置脚本
$regTcpip = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
# 65536,2^16,高并发推荐
New-ItemProperty -Path $regTcpip -Name "MaxHashTableSize" -Value 65536 -PropertyType DWord -Force
New-ItemProperty -Path $regTcpip -Name "MaxFreeTcbs" -Value 200000 -PropertyType DWord -Force
New-ItemProperty -Path $regTcpip -Name "TcpNumConnections" -Value 16000000 -PropertyType DWord -Force
Write-Host "TCB&哈希表参数写入完成,重启生效"
1. TCP SACK / RSCP / ECN 内核参数完整解构
1.1 核心总览
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters1.2 SACK(选择性确认)
底层原理
依赖文件
依赖关系
逻辑链路
配套注册表
SackEnabled:0关闭 / 1开启(默认1)边界坑点
-
DDoS 攻击场景下,部分防护设备会强制屏蔽 SACK,导致协商失败
-
极老旧设备不兼容,关闭 SACK 可解决极个别业务异常
-
高无损内网环境,SACK 性能收益不明显
1.3 RSCP(接收方缩放窗口)
底层原理
依赖关系
配套注册表
TcpWindowScaling 默认开启边界
1.4 ECN(显式拥塞通知)
底层原理
配套注册表
ECNEnabled-
0:关闭(默认)
-
1:开启
-
2:系统自主决策
边界坑点
-
大量老旧防火墙、负载均衡不识别 ECN 标记,导致报文丢弃、连接闪断
-
公网业务不建议主动开启,内网专线可开启优化延迟抖动
2. Windows RSS / VMQ 网卡硬件卸载原理
2.1 背景瓶颈
2.2 RSS(Receive Side Scaling)接收端缩放
底层原理
依赖文件
逻辑链路
配套链
边界
-
物理机强烈建议开启,虚拟机 RSS 性能收益有限
-
部分杂牌网卡 RSS 哈希异常导致流量不均
2.3 VMQ(Virtual Machine Queue)虚拟机队列
底层原理
依赖关系
边界
-
VMQ 与部分网卡节能参数冲突,导致随机丢包
-
容器环境不使用 VMQ,仅虚拟机使用
3. Windows 内核网络抓包(netsh etl + WPR 解析)
3.1 底层原理
3.2 依赖文件
3.3 完整操作链路
开始抓包(内核级)
复现问题后停止
解析 ETL 文件
-
NDIS 层丢包
-
WFP 过滤丢弃
-
TCP 重传、SACK、ECN 事件
-
AFD 缓冲区溢出
3.4 优势与边界
-
✅ 可抓到 Wireshark 抓不到的「内核静默丢包」
-
✅ 可定位防火墙/EDR/WFP 拦截
-
❌ ETL 文件无法直接用 Wireshark 打开,必须 WPR 解析
-
❌ 高并发抓包会轻微损耗性能
4. TCP 零拷贝在内核中的实现
4.1 传统拷贝瓶颈
4.2 Windows 零拷贝底层原理
4.3 完整逻辑链路
4.4 依赖与边界
-
仅支持文件发送,不支持任意内存缓冲区
-
IOCP 模型下零拷贝收益最大
-
小包场景零拷贝收益极低,甚至更慢
-
UDP 不支持零拷贝发送
5. 生产环境网络故障应急处置预案(标准化 SOP)
5.1 故障分级
-
P0:全网断连、业务雪崩
-
P1:随机丢包、抖动、部分用户异常
-
P2:性能慢、吞吐低、延迟高
5.2 一键应急止血流程(优先执行)
-
关闭第三方 EDR/防火墙 WFP 驱动(90% 随机丢包根源)
-
重启 BFE 服务:Restart-Service BFE -Force
-
检查非分页池泄漏:poolmon 观察 Afd/Tcp/Wfp
-
核对 TIME_WAIT / SYN_RCVD 队列溢出
-
临时调优:TcpTimedWaitDelay=30、MaxUserPort=65534
-
必要时重启网卡/整机(内核内存泄漏唯一快速止血方式)
5.3 分层定位 SOP
第一层:物理层
第二层:系统内核层
第三层:WFP/安全软件层
第四层:业务层
5.4 高频故障快速判定表
|
现象
|
根因概率最高项
|
|---|---|
|
新建连接报 10055
|
AFD 上限/非分页池耗尽/Socket泄漏
|
|
大量 TIME_WAIT、无法新建出站
|
端口池耗尽、TcpTimedWaitDelay 过大
|
|
UDP 静默丢包
|
DefaultReceiveWindow 过小、内核缓冲区满
|
|
内核 CPU 高
|
MaxHashTableSize 过小、哈希冲突、RSS未开启
|
|
随机闪断、无规律丢包
|
EDR/WFP 驱动内存泄漏、LSP损坏
|
5.5 复盘归档标准

浙公网安备 33010602011771号