連接埠耗盡問題疑難排解
適用於: Windows 10
TCP 和 UDP 通訊協定會根據用來建立連線的埠號碼運作。 任何需要建立 TCP/UDP 連線的應用程式或服務都需要其端的埠。
埠有兩種類型:
- 暫時埠是動態埠,預設是每部計算機都必須進行輸出連線的埠集。
- 已知的埠是特定應用程式或服務的已定義埠。 例如,檔案伺服器服務位於連接埠 445、HTTPS 是 443、HTTP 是 80,以及 RPC 是 135。 自訂應用程式也會有自己的已定義埠號碼。
與應用程式或服務建立連線時,用戶端裝置會使用來自裝置的暫時埠來連線到針對該應用程式或服務定義的已知埠。 用戶端電腦上的瀏覽器會使用暫時埠連線到 https://www.microsoft.com
埠 443。
在相同瀏覽器建立多個網站的許多連線的情況下,針對瀏覽器嘗試的任何新連線,會使用暫時埠。 經過一段時間之後,您會注意到連線將會開始失敗,而此失敗的可能性很大,是因為瀏覽器已使用所有可用的埠進行外部連線,而任何建立連線的新嘗試都會失敗,因為沒有可用的埠。 使用機器上的所有埠時,我們會將其稱為埠耗盡。
TCP/IP 的預設動態連接埠範圍
為了符合 因特網指派的數位授權單位 (IANA) 建議,Microsoft已增加連出連線的動態用戶端埠範圍。 新的預設起始連接埠是 49152,而新的預設結束連接埠是 65535。 此增加是舊版 Windows 設定的變更,其使用預設埠範圍 1025 到 5000。
您可以使用下列 netsh
命令來檢視電腦上的動態埠範圍:
-
netsh int ipv4 show dynamicport tcp
-
netsh int ipv4 show dynamicport udp
-
netsh int ipv6 show dynamicport tcp
-
netsh int ipv6 show dynamicport udp
針對每個傳輸 (TCP 或 UDP),分別設定範圍。 連接埠範圍現在是具有起始點和結束點的範圍。 Microsoft部署執行 Windows Server 的伺服器的客戶,如果內部網路上使用防火牆,可能會影響伺服器之間的 RPC 通訊。 在這些情況下,建議您重新設定防火牆,以允許 49152 到 65535 的動態埠範圍中的伺服器之間的流量。 此範圍除了服務和應用程式所使用的已知埠之外。 或者,伺服器所使用的埠範圍可以在每部伺服器上修改。 您可以使用 netsh 命令來調整此範圍,如下所示。 上述命令會設定 TCP 的動態埠範圍。
netsh int <ipv4|ipv6> set dynamic <tcp|udp> start=number num=range
啟動埠是數位,而埠總數是範圍。 以下是範例命令:
-
netsh int ipv4 set dynamicport tcp start=10000 num=1000
-
netsh int ipv4 set dynamicport udp start=10000 num=1000
-
netsh int ipv6 set dynamicport tcp start=10000 num=1000
-
netsh int ipv6 set dynamicport udp start=10000 num=1000
這些範例命令會將動態埠範圍設定為從埠 10000 開始,並結束於埠 10999 (1000 埠)。 連接埠的最小範圍可設為 255。 最小開始連接埠可設為 1025。 最大結束埠 (根據所設定的範圍) 不能超過 65535。 若要複製 Windows Server 2003 的預設行為,請使用 1025 作為啟動埠,然後使用 3976 作為 TCP 和 UDP 的範圍。 此使用模式會導致啟動埠 1025 和結束埠 5000。
具體而言,關於連入連線的輸出連線,不需要暫時埠來接受連線。
由於輸出連線開始失敗,您會看到下列許多行為實例:
雖然可透過本機帳戶進行登入,但無法透過網域認證登入電腦。 網域登入會要求您連絡DC以進行驗證,這再次是輸出連線。 如果您已設定快取認證,則網域登入可能仍可運作。
群組原則更新失敗:
無法存取檔案共用:
來自受影響伺服器的 RDP 失敗:
計算機上執行的任何其他應用程式都會開始發出錯誤
伺服器重新啟動會暫時解決問題,但您會看到所有徵兆會在一段時間後恢復。
如果您懷疑機器處於埠耗盡狀態:
請嘗試進行輸出連線。 從伺服器/計算機存取遠端共用,或嘗試 RDP 至另一部伺服器或 telnet 到埠上的伺服器。 如果所有這些選項的輸出連線失敗,請移至下一個步驟。
開啟事件檢視器,並在系統記錄下尋找清楚指出目前狀態的事件:
事件識別碼 4227
事件識別碼 4231
netstat -anob
從伺服器收集輸出。 netstat 輸出會顯示單一 PID TIME_WAIT狀態的大量專案。在正常關閉或會話突然關閉之後,在 4 分鐘(預設)之後,進程或應用程式所使用的埠將會釋放回可用的集區。 在這 4 分鐘內,TCP 的連線狀態將處於 TIME_WAIT 狀態。 在您懷疑埠耗盡的情況下,應用程式或進程將無法釋放它已取用的所有埠,而且會維持在TIME_WAIT狀態。
您可能也會在相同的輸出中看到CLOSE_WAIT狀態連線;不過,當 TCP 對等的一端沒有其他數據傳送(FIN 傳送),但能夠從另一端接收數據時,CLOSE_WAIT狀態就是狀態。 此狀態不一定表示埠耗盡。
注意
具有TIME_WAIT狀態的巨大連線不一定表示伺服器目前已移出埠,除非已驗證前兩個點。 大量 TIME_WAIT 的連線表示流程正在建立大量 TCP 連線,最終可能也會導致連接埠耗盡。
已更新 Windows 10 中的 Netstat,並新增
-Q
參數以顯示已從時間轉換的埠,如同在 BOUND 狀態中一樣。 已發行的 Windows 8.1 和 Windows Server 2012 R2 更新中包含此功能。 Windows 10 中的 PowerShell CmdletGet-NetTCPConnection
也會顯示這些 BOUND 埠。2016 年 10 月前,netstat 的設定不正確。 修正 netstat、備份移植到 2012 R2、允許 Netstat.exe ,以及在
Get-NetTcpConnection
Windows Server 2012 R2 中正確報告 TCP 或 UDP 連接埠使用量。 請參閱 Windows Server 2012 R2:暫時埠 Hotfix 以深入瞭解。在系統管理員模式中開啟命令提示字元,然後執行下列命令。
Netsh trace start scenario=netconnection capture=yes tracefile=c:\Server.etl
使用網路監視器開啟 server.etl 檔案,並在篩選區段中套用篩選
Wscore_MicrosoftWindowsWinsockAFD.AFD_EVENT_BIND.Status.LENTStatus.Code == 0x209
。 您應該會看到顯示 STATUS_TOO_MANY_ADDRESSES的專案。 如果您找不到任何專案,則伺服器仍未離開埠。 如果您找到項目,即可確認伺服器發生連接埠耗盡問題。
疑難排解連接埠用盡
目的在於識別使用所有連接埠的處理序和應用程式。 下列為一些工具,您可以用於隔離至單一處理序
方法 1
首先查看 netstat 輸出。 如果您使用 Windows 10 或 Windows Server 2016,則可以執行 命令 netstat -anobq
,並檢查進程識別碼是否具有最大專案作為 BOUND。 或者,您也可以執行下列 PowerShell 命令來識別處理序:
Get-NetTCPConnection | Group-Object -Property State, OwningProcess | Select -Property Count, Name, @{Name="ProcessName";Expression={(Get-Process -PID ($_.Name.Split(',')[-1].Trim(' '))).Name}}, Group | Sort Count -Descending
造成連接埠流失的主要原因,即在發生錯誤時,使用者模式處理序未正確關閉。 在使用者模式層級,埠(實際上是套接字)是句柄。 TaskManager 和 ProcessExplorer 都能夠顯示句柄計數,這可讓您識別哪個進程正在取用所有埠。
針對 Windows 7 和 Windows Server 2008 R2,您可以更新 PowerShell 版本以納入上述的 cmdlet。
方法 2
如果方法 1 無法協助您識別程式(在 Windows 10 和 Windows Server 2012 R2 之前),請查看任務管理員:
在詳細數據/進程下新增名為 「handles」 的數據行。
排序資料行控制碼,以識別具有最高控制碼數的處理序。 通常,具有大於 3000 之句柄的程式可能是罪魁禍首,除了 System、lsass.exe、store.exe、sqlsvr.exe 等進程。
如果這些進程以外的任何其他進程都有較高的數位,請停止該程式,然後嘗試使用網域認證登入,並查看其是否成功。
方法 3
如果任務管理員無法協助您識別進程,請使用進程總管來調查問題。
使用處理序總管的步驟:
下載進程總管 並加以 提升許可權。
Alt + 選取數據行標頭、選取 [ 選擇數據行],然後在 [ 處理效能] 索引標籤上新增 [句柄計數]。
選取 [檢視>顯示下方窗格]。
選取 [檢視>下方窗格檢視>句柄]。
選取 [句柄] 數據行,依該值排序。
檢查具有與其較高控制碼計數的處理序 (若您無法建立輸出連線,通常會超過 10,000 個)。
按一下以顯目提示具有高控制碼計數的處理序。
在下方窗格中,下列列出的識別碼為通訊端。 (通訊端在技術方面稱為檔案控制碼)。
File \Device\AFD
有些人是正常的,但大量的他們不是(數十到數千)。 關閉有問題的處理序。 如果這會還原輸出連線,則您已進一步證明應用程式是原因。 連絡該應用程式的供應商。
最後,如果上述方法無法協助您隔離進程,建議您收集問題狀態中機器的完整記憶體轉儲。 傾印會通知您具有控制碼上限的處理序。
因應措施是,重新啟動計算機會讓計算機恢復正常狀態,並協助您暫時解決問題。 然而,當重新開機仍無法解決問題時,您也可以考量使用下列命令,增加電腦上的連接埠數量:
netsh int ipv4 set dynamicport tcp start=10000 num=1000
此命令會將動態埠範圍設定為從埠 10000 開始,並結束於埠 10999 (1000 埠)。 連接埠的最小範圍可設為 255。 最小開始連接埠可設為 1025。 最大結束埠 (根據所設定的範圍) 不能超過 65535。
注意
請注意,增加動態埠範圍不是永久解決方案,而是暫時性。 您必須追蹤哪些進程/處理器會耗用最大數目的埠,並從該程序的觀點進行疑難解答,以找出其耗用如此大量埠的原因。
針對 Windows 7 和 Windows Server 2008 R2,您可以使用下列腳本,以定義的頻率收集 netstat 輸出。 從輸出中,您可以看到埠使用趨勢。
@ECHO ON
set v=%1
:loop
set /a v+=1
ECHO %date% %time% >> netstat.txt
netstat -ano >> netstat.txt
PING 1.1.1.1 -n 1 -w 60000 >NUL
goto loop