04-Windows頻繁開啟和關閉連接埠可能引發的問題 | 07.雜項

來源:互聯網
上載者:User
04-Windows頻繁開啟和關閉連接埠可能引發的問題

鄭昀 20100810 隸屬於《07.雜項》小節

老趙寫了一篇《關於Windows頻繁開啟關閉連接埠時出現的問題》,論述了他從 Windows Web Server 2008 R2 通過 TCP 串連對 Cent OS 下的 MongoDB 資料庫服務做壓力測試,遇到了 Socket 串連資源耗盡,導致程式報告“由於系統緩衝區空間不足或隊列已滿,不能執行通訊端上的操作。”錯誤的情況。

Socket 串連資源耗盡,在 Windows Server 下很常見,如果使用者程式寫得沒問題的話,一般都是微軟(或其他軟體廠商)設定的一些預設參數不合時宜導致的。

我以前寫過一篇《02-Twisted 構建 Web Server 的 Socket 長連結問題 | 07.雜項 | Python》,記述了另外一種 Windows Server 常見問題:在 Python 開發語言下,用 twisted 架構編寫一個 Web Server ,接收 Google PubSubHubbub 的 Hub Server 推送過來的 Google Reader 文章共用資訊時,遇到了檔案描述符到達上限的現象。這個模式的特點是,用 twisted.web.server 對接 PubSubHubbub Hub Server ,雙方都支援重用串連,照理說,既然保持長串連並且重用 socket 串連,不應該出現這種“too many file descriptors in select”錯誤。這裡的知識點是 Windows 下 select module 檔案描述符(file descriptor)最多是512個,而在 Linux 下這個限制為 32767 ,如果超過這個限制值,就會出現類似上面的異常。

 

老趙的文章指出了一個有意思的知識點:臨時連接埠號碼可分配範圍, 

臨時連接埠號碼範圍定義

當一個用戶端程式(比如說一個瀏覽器)初始化一個 connection 串連遠端服務(比如一個網站)時,用戶端會開啟一個“ephemeral(臨時)”連接埠,連接埠號碼一般是隨機分配的。你可以用微軟工具 TCPView 來查看。

那麼這個進程為出站串連(outbound connection)分配連接埠號碼時,連接埠號碼的可分配範圍與作業系統有關。其中一個主要影響因素是 MaxUserPort ,位於註冊表的 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters 下。

下面這張表列出了不同 Windows 作業系統所能分配的連接埠範圍:

作業系統

MaxUserPort
數值的
含義

連接埠範圍,如果MaxUserPort
沒有定義

連接埠範圍,如果MaxUserPort
已定義

最小值

最大值

Windows NT/2000/XP/2003

Ending Port

1025 to 5000

1025 to [MaxUserPort]

5000

65535

Windows 2000/XP/2003 with KB951748/KB951746

Ending Port

49152 to 65535

1025 to [MaxUserPort]

5000

65535

Windows Vista/2008

Number of Ports

49152 to 65535

49152 to [49152 + MaxUserPort − 1]

255

16384†

表1 連接埠範圍

當然,你如果在伺服器上安裝了微軟的一些服務,還是會自動修改這個 MaxUserPort 參數的,比如Small Business Server 2000/2003 會修改為 60000, ISA Server 會修改為 65535, Exchange Server 2003 會改為 60000 。

看了這張表後,你會知道:

1、不要使用小於1025的連接埠號碼;

2、盡量使用系統臨時連接埠範圍(ephemeral port range)之外的連接埠,比如你定義自己應用程式要開啟的連接埠號碼為8000,而不是5000。

3、重用串連。

查看了我的筆記本電腦(Win XP)和伺服器(Windows 2003),註冊表裡都沒有設定過這個MaxUserPort參數,所以連接埠範圍就是預設的,在伺服器上,可分配的臨時連接埠是從1025到5000。

 

回到我的檔案描述符開啟過多的問題上,

重用連接埠失敗+保持長串連生效

如果監聽的 Google Reader User 足夠多,這些使用者又在一個時段集中分享文章,那麼 Google PubSubHubub Hub Server 就會以極快的速度把資料推送過來,此時如果重用 socket 連接埠失敗,而保持長串連策略又起作用,於是很快在 twisted web server 監聽的連接埠上開啟的檔案描述符又爆了。

處理辦法:

1、參考《02-Twisted 構建 Web Server 的 Socket 長連結問題 | 07.雜項 | Python》,

twisted.web.server.Site 類的初始化函數有一個選擇性參數 timeout ,它的預設值是 60*60*12 ,也就是12小時,它的目的是閑置連接埠逾時自動關閉。在我們的情景下,逾時時間太長,所以才會有許多處於 ESTABLISHED 狀態的 Socket Connections 積累。

所以我們縮短為 15 分鐘(也可以更短),讓沒有得到重用的 Connections 儘快自動關閉。只需要在開始執行:
reactor.listenTCP(8080, Site(MyWebResource.setup(),timeout=60*15))
即可。

2、參考《03-PubSubHubbub 和 twisted 的 Persistent connections 能力 | 07.雜項 | Python》,接收到對方 Server 推送過來的資料後,非同步扔給另一個方法解析和處理,render_POST 方法立刻 return NOT_DONE_YET 標誌, 等非同步處理資料成功了,回調裡再 finish 掉當前的 request 。

 

參考資源:

1、關於Windows頻繁開啟關閉連接埠時出現的問題 ;

2、Choosing a TCP Port for a Network Service ;

3、02-Twisted 構建 Web Server 的 Socket 長連結問題 | 07.雜項 | Python ;

4、03-PubSubHubbub 和 twisted 的 Persistent connections 能力 | 07.雜項 | Python

5、TCP - WAIT狀態及其對繁忙的伺服器的影響 。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.