在 Windows Server 故障轉移叢集中設定 IIS World Wide Web Publishing Service
本文說明如何在 Windows Server 故障轉移叢集 (WSFC) 中設定 Microsoft 網際網路資訊服務 (IIS) 萬維網發佈服務 (W3SVC)。
原始產品版本:Windows Server 2008 和更新版本、網際網路資訊服務 8.0 和更新版本
原始 KB 編號: 970759
簡介
本文中的程式僅適用於萬維網發佈服務。 如需如何在故障轉移叢集中設定 FTP 發佈服務的指示,請參閱 如何在 Windows Server 故障轉移叢集中設定 IIS 的 FTP。
其他相關資訊
在舊版 網際網路資訊服務 中,Microsoft提供一般資源監視元件,以支援使用 Microsoft 叢集基礎結構的高可用性 Web 伺服器實例。 不過,需要自定義程式代碼才能充分瞭解這類解決方案的潛力。 此外,Microsoft提供的一般腳本不符合客戶需求。 若要在使用 Windows Server 故障轉移叢集的叢集環境中設定 IIS 7.0 或更新版本,您必須使用自定義(腳本)程式代碼來啟用這類高可用性案例。 當您這麼做時,用戶可以自定義設定以符合其需求。 可讓他們完全控制 Web 應用程式的高可用性整合。 此外,IIS 7.0 中引進的管理和監視腳本介面提供比先前提供的腳本更豐富的環境。
注意
IIS 7.0 安裝檔案錯誤地包含 IIS 6.0 中 IIS 叢集系統管理工作的 Clusweb.vbs 和 Clusftp.vbs 腳本檔案。 請勿搭配 IIS 7.0 或更新版本使用這些腳本。
我們建議系統管理員仔細評估使用網路負載平衡 (NLB) 作為改善 Web 應用程式延展性和可用性的主要和慣用方法,以及執行 IIS 7.0 或更新版本的多部伺服器,而不是使用故障轉移叢集。 NLB 的優點之一是所有伺服器都可以積极參與同時處理傳入的超文本傳輸通訊協定 (HTTP) 要求。 另一個優點是,在 NLB IIS 環境中,支援輪流更新和復原,同時仍提供 Web 應用程式的高可用性可能更容易。 如需在 NLB 環境中使用 IIS 7.0 或更新版本的詳細資訊,請參閱下列文章:
請務必考慮,透過叢集 IIS 服務來叢集 IIS 並不一定能保證 Web 應用程式的高可用性解決方案。 雖然 IIS 服務(特別是 WWW 服務)可能已啟動並執行,但特定應用程式集區的裝載進程可能已終止,或應用程式可能會擲回內部伺服器 HTTP 錯誤。 使用自定義腳本將 Web 應用程式叢集和監視其健康情況,是使用故障轉移叢集達到高可用性 IIS 叢集的正確和建議方式。 以下是監視應用程式集區狀態的範例腳本,以判斷它是否已啟動。
若要使用故障轉移叢集設定 IIS 7.0 或更新版本的 Web 伺服器高可用性,請遵循下列步驟。 下面詳細說明步驟 3 到 7。 本文稍後的範例腳本可作為 IIS 7.0 或更新版本的範例。
- 在所有叢集節點上安裝網頁伺服器角色。 如需詳細資訊,請參閱 IIS 7 部署指南。
- 在所有叢集節點上安裝故障轉移叢集功能,並建立叢集。 如需詳細資訊,請參閱 故障轉移叢集部署指南。
- 設定將用於 IIS 共用組態的檔案共用。
- 在所有叢集節點上設定 IIS 共用設定。
- 針對所有叢集節點上的共享設定設定 IIS 離線檔案。
- 設定網站 (包括相關聯的應用程式集區),並指定其內容在一個叢集節點上的位置。
- 在故障轉移叢集中建立一般腳本,以設定網站的高可用性。
設定將用於 IIS 共用設定的檔案共用
- 建立將存取將用於 IIS 共用組態之共用的使用者。
- 建立檔案共用。 此共用將用來儲存所有叢集節點上 IIS 之間共用的 IIS 共用組態。 有多個選項:
- 在不屬於任何故障轉移叢集的獨立伺服器上,建立檔案共用。
- 在另一個 Windows Server 故障轉移叢集上,建立高可用性檔案共用。 如需詳細資訊,請流覽 故障轉移叢集逐步指南:設定雙節點檔伺服器故障轉移叢集。
- 在將裝載高可用性網站的相同故障轉移叢集上,建立高可用性檔案共用。 如需詳細資訊,請參閱 故障轉移叢集逐步指南:設定雙節點檔伺服器故障轉移叢集。
- 設定您在步驟 2 中建立之共享的許可權。 提供您在步驟 1 完整控制權限中建立的使用者檔案共用和 NTFS 許可權。
- 確認所有叢集節點都可以流覽至檔案共用。 檔案共享的路徑為
\\<fileserver>\<share>
。
在所有叢集節點上設定 IIS 共用設定
注意
Windows 2008 Server 上的 IIS 共用設定發生問題,因為缺少 Application Host Helper Service
的許可權。 若要讓共用組態能夠運作,當您在 Windows 2008 Server 上設定 IIS 共用設定時,必須遵循這些步驟。
開啟系統管理命令提示字元。
執行以下命令:
net stop apphostsvc
執行以下命令:
sc privs apphostsvc SeChangeNotifyPrivilege/SeTcbPrivilege/SeImpersonatePrivilege
執行以下命令:
net start apphostsvc
在叢集中的每個 Windows 2008 伺服器上完成這些步驟之後,請繼續設定 IIS 共用設定,如本節所述。
在其中一個叢集節點上,將共用組態導出至檔案共用:
- 流覽至 [系統管理工具],然後選取 [網際網路資訊服務 [IIS] 管理員。
- 在左窗格中,選取 伺服器名稱 節點。
- 按兩下 [共享組態 ] 圖示。
- 在 [共用組態] 頁面上,選取 [動作] 窗格中的 [匯出組態] 窗格(右窗格),將組態檔從本機計算機匯出到另一個位置。
- 在 [匯出組態] 對話框中,於 [實體路徑] 方塊中輸入檔案共享的路徑 。
\\<fileserver>\<share>
- 選取 [ 聯機身分],然後輸入具有共用組態儲存共用存取權之用戶帳戶的使用者名稱和密碼,然後選取 [ 確定]。 此帳戶將用來存取共用。 您應該使用非網域系統管理員的受限制 Active Directory 帳戶。
- 在 [ 匯出組態 ] 對話框中,輸入將用來保護加密密鑰的密碼,然後選取 [ 確定]。
- 在 [ 共享組態 ] 頁面上,選取 [ 啟用共用組態 ] 複選框。
- 輸入實體路徑、用戶帳戶和您先前輸入的密碼,然後在 [動作] 窗格中選取 [套用]。
- 在 [ 加密密鑰密碼 ] 對話框中,輸入您稍早設定的加密金鑰密碼,然後選取 [ 確定]。
- 在 [ 共享組態 ] 對話框中,選取 [ 確定]。
- 選取 [確定]。
在所有其他叢集節點上,使用您剛匯出至檔案共享的共享組態:
- 流覽至 [系統管理工具],然後選取 [網際網路資訊服務 [IIS] 管理員。
- 選取伺服器名稱節點。
- 按兩下 [共享組態 ] 圖示。
- 在 [ 共享組態 ] 頁面上,選取 [ 啟用共用組態 ] 複選框。
- 輸入檔案共享的實體路徑 (
\\<fileserver>\<share>
)、用戶帳戶,以及您先前輸入的密碼,然後在 [動作] 窗格中選取 [套用]。 - 在 [ 加密密鑰密碼 ] 對話框中,輸入您稍早設定的加密金鑰密碼,然後選取 [ 確定]。
- 在 [ 共享組態 ] 對話框中,選取 [ 確定]。
- 選取 [確定]。
注意
如需如何在 IIS 中設定共用組態的詳細資訊,請瀏覽 共用組態。
在所有叢集節點上設定 IIS 離線檔案以進行共享設定
在每個叢集節點上,啟用離線檔案:
安裝桌面體驗
- 流覽至 [系統管理工具],然後選取 [伺服器管理員]。
- 在左窗格中,選取 [ 功能]。
- 選取 右窗格中的 [新增功能 ]。
- 請視您的 Windows 版本執行下列其中一項動作:
- 如需 Windows Server 2016,請瀏覽 安裝具有桌面體驗的伺服器。
- 針對 Windows Server 2102 和 2012 R2,選擇功能清單中的 [使用者介面和基礎結構] 下的 [桌面體驗]。
- 針對 Windows Server 2008 和 2008 R2,選擇 [ 桌面體驗]。
- 選取 [ 安裝 ] 以安裝桌面體驗。
- 重新啟動電腦。
執行下列其中一項動作:
- 針對 Windows Server 2012、2012 R2 和 2016,選取 [控制台 中的同步中心],然後選取 [管理脫機檔案]。
- 針對 Windows Server 2008 和 2008 R2,選取 [控制台 中的脫機檔案]。
選取 [ 啟用離線檔案]。 目前請勿重新啟動電腦。
確定快取設定為唯讀。 若要這樣做,請在提升許可權的 Cmd 提示字元中執行下列命令:
REG ADD "HKLM\System\CurrentControlSet\Services\CSC\Parameters" /v ReadOnlyCache /t REG_DWORD /d 1 /f
重新啟動電腦。
從電腦瀏覽至檔案伺服器。 以滑鼠右鍵按兩下包含 IIS 共用組態的共享,然後選取 [ 永遠可用離線]。
注意
如果您在裝載 IIS 節點的相同故障轉移叢集上將檔案共享設定為高可用性,當您以滑鼠右鍵按兩下共用時, 如果裝載高可用性文件伺服器的叢集節點,[永遠可用離線 ] 選項將不會顯示。 您必須將高可用性檔案伺服器應用程式移至另一個節點。
在 控制台 中,開啟 [脫機檔案]。 選取 [ 開啟同步中心],然後選取 [ 排程]。
排程每天或根據您的需求進行離線檔案同步處理。 您也可以將離線同步處理設定為每隔幾分鐘執行一次。 即使您未設定排程器,當您變更 Applicationhost.config 檔案中的某個專案時,變更也會反映在網頁伺服器上。
注意
如需如何在 IIS 中為共用組態設定離線檔案的詳細資訊,請參閱 共用組態的離線檔案。
設定網站,並指定其內容在一個叢集節點上的位置
尋找擁有叢集磁碟資源的叢集節點,其中網站內容檔案會保留:
- 流覽至 [系統管理工具],然後選取 [故障轉移叢集管理員]。
- 連線至叢集。 如果您位於其中一個叢集節點上,叢集會自動出現在清單中。
- 在 [記憶體] 底下,尋找網頁內容所在的磁碟資源。 若要這樣做,請展開磁碟資源的記憶體樹狀結構。 請確定叢集上任何其他高可用性應用程式都不會使用記憶體。 您會在 [可用的記憶體] 底下找到記憶體。
- 此資源在在線的叢集節點。 您將在該叢集節點上設定 IIS。
- 叢集磁碟資源名稱。
您將針對內容檔案使用此專案。 在資源上線的叢集節點上,將 Web 伺服器設定為使用網站內容的共用磁碟:
- 流覽至 [系統管理工具],然後選取 [網際網路資訊服務 [IIS] 管理員。
- 在左窗格中,展開伺服器名稱節點。
- 展開 [月臺],然後在 [月臺] 底下,選取您要設定的網站。
- 在右窗格中,選取 [管理網站] 底下的 [進階設定]。
- 在 [一般設定] 下找出 [實體路徑] 屬性,然後輸入網站內容檔案所在的位置。 這是您在上一個程式的步驟 5 中指出的叢集磁碟資源位置。
- 選取 [確定]。
在故障轉移叢集管理員中建立一般腳本,以設定網站的高可用性
若要為 IIS Web 伺服器設定高可用性的最後一個步驟,請設定將用來監視網站的網站和應用程式集區的一般腳本資源:
在每個叢集節點上,將本文
Windows\System32\inetsrv\Clusweb7.vbs
結尾所提供的文稿複製到 。根據預設,腳本會監視名為 Default Web Site 的網站 ,以及名為 DefaultAppPool 的應用程式集區。 如果這些不是正確的網站和應用程式集區,請變更
SITE_NAME and APP_POOL_NAME
變數。 請確定文稿中的所有叢集節點上都有相同的網站和應用程式集區。注意
名稱會區分大小寫。
流覽至 [系統管理工具],然後選取 [故障轉移叢集管理員]。
連線至叢集。 如果您位於其中一個叢集節點上,叢集會自動出現在清單中。
執行下列其中一項動作:
- 針對 Windows Server 2012、2012 R2 和 2016,以滑鼠右鍵按兩下 [角色 ],然後選取 [ 設定角色 ] 來建立它。
- 針對 Windows Server 2008 和 2008 R2,以滑鼠右鍵按兩下叢集,然後選取 [ 設定服務或應用程式]。 精靈會建立高可用性工作負載。
選取 [一般腳本]。
從
%systemroot%\System32\Inetsrv\clusweb7.vbs
選取腳本檔案。將用戶端存取點 (CAP) 名稱設定為用戶端將用來連線到高可用性網站的網站名稱。 指定要用於網站 CAP 的靜態 IP。 如果您使用動態主機設定通訊協定 (DHCP),將不會顯示此選項。
在 [ 選取記憶體] 步驟中,選取網站內容檔案所在的叢集共用磁碟。 叢集上任何其他高可用性應用程式都應該使用記憶體。
注意
如果用於 IIS 共用設定的檔案共享裝載在相同的叢集上,則應該在這裡使用不同的磁碟資源。
確認設定之後,精靈會建立叢集群組、叢集資源,以及資源之間的相依性,然後讓資源上線。
注意
若要在相同的故障轉移叢集上裝載多個高可用性網站,請遵循與上述相同的步驟。 不過,針對每個網站和不同的叢集共用記憶體使用不同的腳本檔案。 例如,在 中
%systemroot%\System32\Inetsrv
,針對第一個網站使用 clusweb7.vbs、針對第二個網站使用 clweb7-2.vbs、針對第三個網站使用 clweb7-3.vbs 等等。 每個腳本檔案都會監視不同的網站和應用程式集區。
下列腳本僅供範例使用,Microsoft並未明確支援。 在 IIS 7.0 或更新版本的叢集環境中使用此腳本會自行承擔風險。
'<begin script sample>
'This script provides high availability for IIS websites
'By default, it monitors the "Default Web Site" and "DefaultAppPool"
'To monitor another website, change the SITE_NAME below
'To monitor another application pool, change the APP_POOL_NAME below
'More thorough and application-specific health monitoring logic can be added to the script if needed
Option Explicit
DIM SITE_NAME
DIM APP_POOL_NAME
Dim START_WEB_SITE
Dim START_APP_POOL
Dim SITES_SECTION_NAME
Dim APPLICATION_POOLS_SECTION_NAME
Dim CONFIG_APPHOST_ROOT
Dim STOP_WEB_SITE
'Note:
'Replace this with the site and application pool you want to configure high availability for
'Make sure that the same website and application pool in the script exist on all cluster nodes. Note that the names are case-sensitive.
SITE_NAME = "Default Web Site"
APP_POOL_NAME = "DefaultAppPool"
START_WEB_SITE = 0
START_APP_POOL = 0
STOP_WEB_SITE = 1
SITES_SECTION_NAME = "system.applicationHost/sites"
APPLICATION_POOLS_SECTION_NAME = "system.applicationHost/applicationPools"
CONFIG_APPHOST_ROOT = "MACHINE/WEBROOT/APPHOST"
'Helper script functions
'Find the index of the website on this node
Function FindSiteIndex(collection, siteName)
Dim i
FindSiteIndex = -1
For i = 0 To (CInt(collection.Count) - 1)
If collection.Item(i).GetPropertyByName("name").Value = siteName Then
FindSiteIndex = i
Exit For
End If
Next
End Function
'Find the index of the application pool on this node
Function FindAppPoolIndex(collection, appPoolName)
Dim i
FindAppPoolIndex = -1
For i = 0 To (CInt(collection.Count) - 1)
If collection.Item(i).GetPropertyByName("name").Value = appPoolName Then
FindAppPoolIndex = i
Exit For
End If
Next
End Function
'Get the state of the website
Function GetWebSiteState(adminManager, siteName)
Dim sitesSection, sitesSectionCollection, siteSection, index, siteMethods, startMethod, executeMethod
Set sitesSection = adminManager.GetAdminSection(SITES_SECTION_NAME, CONFIG_APPHOST_ROOT)
Set sitesSectionCollection = sitesSection.Collection
index = FindSiteIndex(sitesSectionCollection, siteName)
If index = -1 Then
GetWebSiteState = -1
End If
Set siteSection = sitesSectionCollection(index)
GetWebSiteState = siteSection.GetPropertyByName("state").Value
End Function
'Get the state of the ApplicationPool
Function GetAppPoolState(adminManager, appPool)
Dim configSection, index, appPoolState
set configSection = adminManager.GetAdminSection(APPLICATION_POOLS_SECTION_NAME, CONFIG_APPHOST_ROOT)
index = FindAppPoolIndex(configSection.Collection, appPool)
If index = -1 Then
GetAppPoolState = -1
End If
GetAppPoolState = configSection.Collection.Item(index).GetPropertyByName("state").Value
End Function
'Start the w3svc service on this node
Function StartW3SVC()
Dim objWmiProvider
Dim objService
Dim strServiceState
Dim response
'Check to see if the service is running
set objWmiProvider = GetObject("winmgmts:/root/cimv2")
set objService = objWmiProvider.get("win32_service='w3svc'")
strServiceState = objService.state
If ucase(strServiceState) = "RUNNING" Then
StartW3SVC = True
Else
'If the service is not running, try to start it
response = objService.StartService()
'response = 0 or 10 indicates that the request to start was accepted
If ( response <> 0 ) and ( response <> 10 ) Then
StartW3SVC = False
Else
StartW3SVC = True
End If
End If
End Function
'Start the application pool for the website
Function StartAppPool()
Dim ahwriter, appPoolsSection, appPoolsCollection, index, appPool, appPoolMethods, startMethod, callStartMethod
Set ahwriter = CreateObject("Microsoft.ApplicationHost.WritableAdminManager")
Set appPoolsSection = ahwriter.GetAdminSection(APPLICATION_POOLS_SECTION_NAME, CONFIG_APPHOST_ROOT)
Set appPoolsCollection = appPoolsSection.Collection
index = FindAppPoolIndex(appPoolsCollection, APP_POOL_NAME)
Set appPool = appPoolsCollection.Item(index)
'See if it is already started
If appPool.GetPropertyByName("state").Value = 1 Then
StartAppPool = True
Exit Function
End If
'Try To start the application pool
Set appPoolMethods = appPool.Methods
Set startMethod = appPoolMethods.Item(START_APP_POOL)
Set callStartMethod = startMethod.CreateInstance()
callStartMethod.Execute()
'If started return true, otherwise return false
If appPool.GetPropertyByName("state").Value = 1 Then
StartAppPool = True
Else
StartAppPool = False
End If
End Function
'Start the website
Function StartWebSite()
Dim ahwriter, sitesSection, sitesSectionCollection, siteSection, index, siteMethods, startMethod, executeMethod
Set ahwriter = CreateObject("Microsoft.ApplicationHost.WritableAdminManager")
Set sitesSection = ahwriter.GetAdminSection(SITES_SECTION_NAME, CONFIG_APPHOST_ROOT)
Set sitesSectionCollection = sitesSection.Collection
index = FindSiteIndex(sitesSectionCollection, SITE_NAME)
Set siteSection = sitesSectionCollection(index)
if siteSection.GetPropertyByName("state").Value = 1 Then
'Site is already started
StartWebSite = True
Exit Function
End If
'Try to start site
Set siteMethods = siteSection.Methods
Set startMethod = siteMethods.Item(START_WEB_SITE)
Set executeMethod = startMethod.CreateInstance()
executeMethod.Execute()
'Check to see if the site started, if not return false
If siteSection.GetPropertyByName("state").Value = 1 Then
StartWebSite = True
Else
StartWebSite = False
End If
End Function
'Stop the website
Function StopWebSite()
Dim ahwriter, sitesSection, sitesSectionCollection, siteSection, index, siteMethods, startMethod, executeMethod, autoStartProperty
Set ahwriter = CreateObject("Microsoft.ApplicationHost.WritableAdminManager")
Set sitesSection = ahwriter.GetAdminSection(SITES_SECTION_NAME, CONFIG_APPHOST_ROOT)
Set sitesSectionCollection = sitesSection.Collection
index = FindSiteIndex(sitesSectionCollection, SITE_NAME)
Set siteSection = sitesSectionCollection(index)
'Stop the site
Set siteMethods = siteSection.Methods
Set startMethod = siteMethods.Item(STOP_WEB_SITE)
Set executeMethod = startMethod.CreateInstance()
executeMethod.Execute()
End Function
'Cluster resource entry points. More details here:
'http://msdn.microsoft.com/en-us/library/aa372846(VS.85).aspx
'Cluster resource Online entry point
'Make sure the website and the application pool are started
Function Online( )
Dim bOnline
'Make sure w3svc is started
bOnline = StartW3SVC()
If bOnline <> True Then
Resource.LogInformation "The resource failed to come online because w3svc could not be started."
Online = False
Exit Function
End If
'Make sure the application pool is started
bOnline = StartAppPool()
If bOnline <> True Then
Resource.LogInformation "The resource failed to come online because the application pool could not be started."
Online = False
Exit Function
End If
'Make sure the website is started
bOnline = StartWebSite()
If bOnline <> True Then
Resource.LogInformation "The resource failed to come online because the web site could not be started."
Online = False
Exit Function
End If
Online = true
End Function
'Cluster resource offline entry point
'Stop the website
Function Offline( )
StopWebSite()
Offline = true
End Function
'Cluster resource LooksAlive entry point
'Check for the health of the website and the application pool
Function LooksAlive( )
Dim adminManager, appPoolState, configSection, i, appPoolName, appPool, index
i = 0
Set adminManager = CreateObject("Microsoft.ApplicationHost.AdminManager")
appPoolState = -1
'Get the state of the website
if GetWebSiteState(adminManager, SITE_NAME) <> 1 Then
Resource.LogInformation "The resource failed because the " & SITE_NAME & " web site is not started."
LooksAlive = false
Exit Function
End If
'Get the state of the Application Pool
if GetAppPoolState(adminManager, APP_POOL_NAME) <> 1 Then
Resource.LogInformation "The resource failed because Application Pool " & APP_POOL_NAME & " is not started."
LooksAlive = false
Exit Function
End if
'Web site and Application Pool state are valid return true
LooksAlive = true
End Function
'Cluster resource IsAlive entry point
'Do the same health checks as LooksAlive
'If a more thorough than what we do in LooksAlive is required, this should be performed here
Function IsAlive()
IsAlive = LooksAlive
End Function
'Cluster resource Open entry point
Function Open()
Open = true
End Function
'Cluster resource Close entry point
Function Close()
Close = true
End Function
'Cluster resource Terminate entry point
Function Terminate()
Terminate = true
End Function
'<end script sample>