socket 連接配接資源耗盡,在 windows server 下很常見,如果使用者程式寫得沒問題的話,一般都是微軟(或其他軟體廠商)設定的一些預設參數不合時宜導緻的。
老趙的文章指出了一個有意思的知識點:臨時端口号可配置設定範圍,
那麼這個程序為出站連接配接(outbound connection)配置設定端口号時,端口号的可配置設定範圍與作業系統有關。其中一個主要影響因素是 maxuserport ,位于系統資料庫的 hkey_local_machine\system\currentcontrolset\services\tcpip\parameters 下。
下面這張表列出了不同 windows 作業系統所能配置設定的端口範圍:
作業系統
maxuserport
數值的
含義
端口範圍,如果maxuserport
沒有定義
已定義
最小值
最大值
windows nt/2000/xp/2003
ending port
1025 to 5000
1025 to [maxuserport]
5000
65535
49152 to 65535
<a href="http://support.microsoft.com/kb/929851">windows vista/2008</a>
number of ports
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 監聽的端口上打開的檔案描述符又爆了。
處理辦法:
是以我們縮短為 15 分鐘(也可以更短),讓沒有得到重用的 connections 盡快自動關閉。隻需要在開始執行:
reactor.listentcp(8080, site(mywebresource.setup(),timeout=60*15))
即可。