我正在使用 Powershell 通过 EWS API 从 Exchange 提取数据。
Import-Module "C:\ews_api\Microsoft.Exchange.WebServices.dll"
$ExchangeServer = 'EXCHANGE'
$ExchangeService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1)
$ExchangeService.Url = "https://$ExchangeServer/ews/exchange.asmx"
$SearchRootFolder = New-Object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar)
$SearchFolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView([int]::MaxValue)
$SearchResult = $ExchangeService.FindFolders($SearchRootFolder, $SearchFolderView)
执行最后一行代码将导致与 Exchange 服务器建立 HTTP 连接,TIME_WAIT
在 Windows 默认设置下,该连接将处于 TCP 状态 2 分钟。使用大量查询访问 Exchange 服务器将导致TIME_WAIT
同时存在许多会话。
Get-NetTCPConnection | Group-Object State
Count Name
----- ----
28 Listen
10 Bound
5 Established
6 CloseWait
189 TimeWait
Windows 中的会话数似乎有 190 个左右的限制TIME_WAIT
,因为在这个值附近,我在 Powershell 中收到以下错误。
Microsoft.Exchange.WebServices.Data.ServiceRequestException: The request failed. Unable to connect to the remote server
---> System.Net.WebException: Unable to connect to the remote server
---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted 10.50.222.87:443
我认为 Windows 可以分配比 TCP 会话更多的临时端口?事实上,当使用另一个 Powershell 代码示例时,我没有遇到任何问题。
$connections = @()
for ($i = 0; $i -lt 1000; $i++) {
$connections += [System.Net.Sockets.TcpClient]::new($ExchangeServer, 443)
}
打开一千个连接没有问题。但是它们处于 TCP 状态ESTABLISHED
而不是TIME_WAIT
. 为什么我只在会话状态下遇到这个问题TIME_WAIT
,有没有办法增加这个限制?
Get-NetTCPConnection | Group-Object State
Count Name
----- ----
28 Listen
1010 Bound
1003 Established
8 CloseWait
我无法找到有关此类限制的任何文档,但您可以修改套接字保持在 TIME_WAIT 状态的时间量:
https://learn.microsoft.com/en-us/biztalk/technical-guides/settings-that-can-be-modified-to-improve-network-performance
该文章确实建议将其从默认值 (120) 降低到 30 秒,以提高网络性能:
我无法在全新安装的 Windows Server 2022 上重现该问题。首先我认为这与某些组策略设置有关,但事实并非如此。
后来我发现有其他东西限制了每个用户可以分配的端口。在我们的例子中,它是
Palo Alto Networks Terminal Server Agent
. 该代理负责识别终端服务器上的用户,以便防火墙规则可以基于用户应用。不幸的是,这样做的副作用是每个用户的端口受到限制。对我来说,解决方案是使用不存在该代理的另一台服务器。