可能很多朋友都遇到過這個現象:在啟動IIS時,你會發現IIS會將Web網站中配置的服務連接埠(例如TCP 80)綁定在電腦的所有IP地址上,而不僅僅是分配給Web網站的IP地址,這是為什麼呢?
這個特性稱為Socket Pooling(通訊端池)。通訊端(Socket )是IP地址和連接埠的組合,用於進行網路通訊,任何應用程式需要和網路上的其他應用程式進行通許時,必須具有相應的通訊端,例如Web網站偵聽客戶的HTTP請求,那麼它就綁定在相應的通訊端(IP地址和連接埠,例如連接埠為標準的TCP 80)上。在IIS 4.0中,微軟發現當多個Web網站分別通過不同的通訊端綁定在不同的IP地址時,會佔用較多的系統資源,於是在IIS 5.0中引入了Socket Pool(通訊端池)這個概念,它的工作原理是這樣的:IIS啟動時會將所有Web網站配置的服務連接埠綁定在電腦的所有IP地址上(運行Netstat -ano可以看到,這些Web服務連接埠偵聽的IP地址是代表所有IP地址的“0.0.0.0”),而不管這些IP地址是否分配給了這些Web網站,IIS把綁定的這些通訊端稱為通訊端池;然後IIS再將通訊端池中的通訊端根據Web網站的配置分配到相應的Web網站,這樣避免了不同Web網站佔用不同IP地址的相同Web服務連接埠時需要不同的通訊端,從而減少了系統資源的佔用,提高了IIS的效能。
需要注意的是,Web網站所分配的IP地址是從IIS的通訊端池中進行再分配的,因此你不能分配通訊端池中不具有的IP地址給Web網站,這會導致Web網站無法工作。
IIS的所有組件均具有Socket Pooling特性。雖然這樣提高了IIS的效能,但是也導致了其他應用程式不能再綁定連接埠到這些IP地址上。例如Web網站偵聽TCP 80連接埠,那麼IIS啟動時會偵聽所有IP地址上的TCP 80連接埠,此時如果在ISA防火牆中做Web服務發布,需要偵聽相應的IP地址(例如外部介面的IP地址)上的TCP 80連接埠,那麼ISA防火牆的連接埠綁定就會失敗,因為IIS已經佔用了這些連接埠。
在這篇文章中,我主要給大家介紹如何處理IIS 6中Web服務的Socket Pooling(通訊端池)現象。注意我在此使用的是“現象”這個詞,因為我覺得Socket Pooling並不是問題,雖然很多人都這樣認為。如果你並沒有其他應用程式需要佔用IIS通訊端池中的連接埠,你根本就不需要對Socket Pooling進行任何處理。
還記得在IIS使用指南之一 :IIS 6 新特性一文中所描述的IIS 6的新架構嗎?在IIS 5中,Socket Pooling是作為Metabase的一個可配置屬性出現;而在IIS 6中是由HTTP.sys來偵聽客戶發送的HTTP請求,因此也是由它來處理Socket Pool。HTTP.sys使用一個IP地址包含列表來決定自己偵聽HTTP請求的IP地址,在每次啟動時讀取此列表並依照此列表進行配置。預設情況下,此IP地址包含列表並不包含任何IP地址,因此HTTP.sys偵聽本機電腦的所有IP地址。此IP地址包含列表不能通過IIS管理主控台或者修改Metabase.xml來進行配置,你必須通過微軟提供的Windows支援工具httpcfg來配置。
httpcfg工具專用於HTTP.sys的配置,它作為Windows支援工具,附帶在Windows Server 2003的安裝光碟片中。我們首先需要安裝Windows支援工具,放入Windows Server 2003安裝光碟片,雙擊運行“光碟片根目錄/Support/Tools/”下的Support.msi檔案,跟隨提示進行安裝。
安裝完成後點擊開始、所有程式,指向Windows Support Tools,然後選擇Command Prompt,此時即可運行httpcfg。
我在一台綁定了兩個IP地址的Web伺服器上給大家進行示範,如所示,Web伺服器綁定了10.1.1.9、10.1.1.10這兩個IP地址,IIS中的預設網站的Web服務連接埠是TCP 80,因此HTTP.sys偵聽所有IP地址的80連接埠。
現在我先查詢一下HTTP.sys的IP地址包含列表,運行以下命令:
httpcfg query iplisten
如所示,返回的錯誤碼1168的含義是找不到匹配元素,這代表IP地址包含列表目前沒有任何元素,因此HTTP.sys偵聽本機電腦的所有IP地址。
現在我們為IP地址包含列表添加一個IP地址,例如,我想讓HTTP.sys只是偵聽10.1.1.9這個IP地址,則運行以下命令:
httpcfg set iplisten -i 10.1.1.9
如所示,返回的錯誤碼0代表成功完成。因為HTTP.sys只是在啟動時讀取此IP地址包含列表,所以此時我們需要重啟HTTP.sys。
運行以下命令重啟HTTP.sys:
net stop http /y
net start w3svc
如所示,HTTP.sys成功重啟。
再查詢一下IP地址包含列表和HTTP.sys偵聽Web服務的連接埠,如所示,已經修改為10.1.1.9了。
我們試著在IIS中為Web站台指派一個並未包含在HTTP.sys IP地址包含列表中的IP地址,例如10.1.1.10,
此時,你會發現,此Web網站已經停止服務了,當你試著啟動它時,錯誤提示不能訪問網路位置。
另外需要注意的是,如果你需要通過localhost來訪問Web網站,那麼你需要將環回IP地址127.0.0.1加入到IP地址包含列表中,如所示:
最後,如果你想還原Socket Pool,則刪除IP地址包含列表中的所有IP地址即可,運行以下命令:
httpcfg delete iplisten -i 127.0.0.1
httpcfg delete iplisten -i 10.1.1.9
結果如所示,
然後重啟HTTP.sys即可。