TCP連接時動態埠的相關問題說明
最近在線上遇到一個TCP動態埠相關的問題,之前沒有留意過此類問題,做個筆記記錄在這裡,希望也能給大家提供個參考。
簡單介紹下問題的場景:Windows伺服器上,部署了網關程式SG和RPC進程,其中RPC進程監聽本地8003埠。問題發生在一次線上常規發布的時候,RPC程式會重啟一次載入新部署的程式文件。然而卻啟動失敗了,直接原因是」通常每個套接字地址(協議/網路地址/埠)只允許使用一次。「。於是檢查本地埠佔用情況,發現8003埠確實被佔用了,而且是被網關程式佔用,如下圖所示。
背景資料
-
TCP/IP協議傳輸層建立連接時請求方和目標方都需要分配一個埠號。目標方的埠號自然是提前分配並創建連接時確定具體埠的,但是請求方的埠就採用本地動態埠的策略隨機分配1個使用。
-
動態埠的分配也不是純隨機的,而是根據OS設置,在一個範圍內隨機。可以通過命令查看:
netsh int ipv4 show dynamicport tcp
其中啟動埠就是起始埠,埠數就是動態埠可分配的個數。
也可以通過命令設置起始埠和數量:
netsh int ipv4 set dynamicport tcp start=32765 num=30000
- Windows上動態埠的設置不是一成不變的,簡單來說: 在Windows vista和windows server 2008以前的系統中動態的客戶端埠範圍是1025到5000;在Windows vista和windows server 2008中,為了遵守IANA的推薦,把範圍擴展成49152到65535。
原因分析
根據以上內容,查看了伺服器的動態埠配置,發現確實有問題:
也就是說,作為Socket連接請求方的網關進程,確實可能會從OS獲取到8003埠準備發起連接,所以RPC進程重啟時再次綁定8003自然就失敗了。
解決方案
修改本地動態埠範圍,避開常用的服務埠範圍。
擴展延申
查閱資料時,看到有文章提到埠回收到重用會有時間間隔,根據 RFC793 規範,此值應是網路上最大段生存期的兩倍(2msl),處於這個階段的連接狀態未TIME_WAIT。可以通過註冊表配置此值,路徑:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Services\TCPIP\Parameters,鍵TcpTimedWaitDelay。
參考資料
- //support.microsoft.com/zh-cn/help/929851/the-default-dynamic-port-range-for-tcp-ip-has-changed-in-windows-vista
- //support.microsoft.com/en-us/help/314053/tcp-ip-and-nbt-configuration-parameters-for-windows-xp