共用方式為


Internet Information Services 裝載最佳做法

本主題概述裝載 Windows Communication Foundation (WCF) 服務的一些最佳做法。

將 WCF 服務實作為 DLL

將 WCF 服務實作為部署至 Web 應用程式的 \bin 目錄的 DLL,可讓您重複使用 Web 應用程式模型外部的服務,例如,在可能尚未部署 Internet Information Services (IIS) 的測試環境中。

IIS-Hosted 應用程式中的服務主機

請勿使用命令式自我主機 API 來建立新的服務主機,以接聽 IIS 裝載環境原生不支援的網路傳輸(例如 IIS 6.0 裝載 TCP 服務,因為 IIS 6.0 上原生不支援 TCP 通訊)。 我們不建議您使用這個方式。 在 IIS 裝載環境中,無法識別命令式建立的服務主機。 關鍵點是,當 IIS 判斷主控應用程式集區是否閒置時,命令式建立服務所完成的處理不會由 IIS 負責。 結果是,具有以指令方式建立服務主機的應用程式,擁有一個會積極處理 IIS 主機進程的 IIS 裝載環境。

URI 和 IIS-Hosted 端點

IIS 裝載服務的端點應該使用相對統一資源標識碼(URI),而不是絕對位址來設定。 這可確保端點位址落在屬於主控應用程式的 URI 位址集合內,並確保訊息型啟用會如預期般發生。

狀態管理和進程回收

IIS 裝載環境已針對不會在記憶體中維護本機狀態的服務進行優化。 IIS 會回收主機進程以回應各種外部和內部事件,導致任何以獨佔方式儲存在記憶體中的變動狀態遺失。 裝載在 IIS 中的服務應該將其狀態儲存在進程外部(例如,在資料庫中),或儲存在記憶體內部快取中,如果應用程式回收事件發生,則可以輕鬆地重新建立。

備註

WCF 用於訊息層可靠性和安全性的通訊協定會使用不穩定的記憶體內部狀態。 WCF 可靠會話和安全性會話可能會因為應用程式重新啟動而意外終止。 使用這些通訊協定的 IIS 裝載應用程式應避免依賴 WCF 提供的會話密鑰來關聯應用層狀態,並應考慮使用其他方法(例如應用層構造或自訂關聯標頭),或者停用該裝載應用程式的 IIS 進程回收。

優化 Middle-Tier 場景中的效能

為了在 中階層情境中獲得最佳效能(即一個因應傳入訊息而呼叫其他服務的服務),只需將 WCF 服務用戶端實例化一次,然後在多個傳入請求中重複使用該實例。 實例化 WCF 服務客戶端相較於在現有客戶端實例上進行服務呼叫是一項耗費資源的操作,而在仲介層案例中,透過在多個請求間快取遠端客戶端,可以顯著提高效能。 WCF 服務客戶端是線程安全的,因此不需要在多個線程中同步存取客戶端。

中介層情境也透過使用 svcutil /a 選項產生的異步 API 來提升效能。 此選項 /a 會讓 ServiceModel 元數據公用程式工具 (Svcutil.exe) 為每個服務作業產生 BeginXXX/EndXXX 方法,這可讓背景線程上對遠端服務進行長時間執行的呼叫。

多重家庭網路或多重命名場景中的 WCF

您可以在 IIS Web 伺服器陣列內部署 WCF 服務,其中一組電腦共用一般外部名稱(例如 http://www.contoso.com),但會由不同的主機名個別尋址(例如, http://www.contoso.com 可能會將流量導向兩部名為 http://machine1.internal.contoso.comhttp://machine2.internal.contoso.com的不同計算機)。 WCF 完全支援此部署案例,但需要特殊設定裝載 WCF 服務的 IIS 網站,才能在服務的元數據中顯示正確的(外部)主機名(Web 服務描述語言)。

若要確保 WCF 所產生的服務中繼資料中顯示正確的主機名稱,請設定裝載 WCF 服務的 IIS 網站的預設身分識別,以使用明確的主機名稱。 例如,位於伺服器叢集內部 www.contoso.com 的電腦應該使用 *:80:www.contoso.com for HTTP and *:443:www.contoso.com for HTTPS的 IIS 網站綁定。

您可以使用 IIS Microsoft Management Console (MMC) 嵌入式管理單元來設定 IIS 網站系結。

在不同使用者上下文中運行的應用程式集區會覆寫暫存資料夾中其他帳戶的組件

為了確保在不同使用者上下文中運行的應用程式池無法覆寫暫存 ASP.NET 檔案資料夾中其他帳戶的元件,請為不同的應用程式使用不同的身份識別和暫存資料夾。 例如,如果您有兩個虛擬應用程式 /Application1 和 /Application2,您可以建立兩個應用程式集區 A 和 B,具有兩個不同的身分識別。 應用程式集區 A 可以在一個使用者身分識別下執行(user1),而應用程式集區 B 可以在另一個使用者身分識別下執行 ,並將 /Application1 設定為使用 A 和 /Application2 來使用 B。

在 Web.config中,您可以使用 system.web/compilation/@tempFolder< 來設定暫存資料夾>。 針對 /Application1,它可以是 “c:\tempForUser1”,而針對 application2,它可以是 “c:\tempForUser2”。 為這兩個身份授予這些資料夾的相應寫入權限。

然後 user2 無法變更 /application2 的程式代碼產生資料夾(在 c:\tempForUser1 下)。

啟用異步處理

根據預設,傳送至裝載於 IIS 6.0 和更早版本的 WCF 服務訊息會以同步方式處理。 ASP.NET 在自己的線程上呼叫 WCF(ASP.NET 背景工作線程),WCF 會使用另一個線程來處理要求。 WCF 會保留 ASP.NET 工作執行緒,直到完成處理。 這會導致同步處理要求。 以異步方式處理要求可提高延展性,因為它可減少處理要求所需的執行緒數目 – WCF 在處理要求時不會保留 ASP.NET 執行緒。 不建議在執行 IIS 6.0 的電腦上使用非同步行為,因為無法限制連入要求,這會使伺服器容易受到拒絕服務(DoS)攻擊。 從 IIS 7.0 開始,已引進併發請求限制:[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0]"MaxConcurrentRequestsPerCpu。 有了這個新的節流閥門,使用異步處理是安全的。 根據預設,IIS 7.0 中會註冊異步處理程式和模組。 如果此功能已關閉,您可以手動啟用應用程式 Web.config 檔案中要求的異步處理。 您使用的設定取決於您 aspNetCompatibilityEnabled 的設定。 如果您已將 aspNetCompatibilityEnabled 設定為 false,請如以下組態片段所示配置 System.ServiceModel.Activation.ServiceHttpModule

<system.serviceModel>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
  </system.serviceModel>  
  <system.webServer>  
    <modules>  
      <remove name="ServiceModel"/>  
      <add name="ServiceModel"
           preCondition="integratedMode,runtimeVersionv2.0"
           type="System.ServiceModel.Activation.ServiceHttpModule, System.ServiceModel,Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>  
    </modules>  
    </system.webServer>  

如果您已將 aspNetCompatibilityEnabled 設定為 true,請依照下列組態程式片段的顯示來設定 System.ServiceModel.Activation.ServiceHttpHandlerFactory

<system.serviceModel>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>  
  <system.webServer>  
    <handlers>  
          <clear/>  
          <add name="TestAsyncHttpHandler"
               path="*.svc"
               verb="*"
               type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
               />  
    </handlers>
  </system.webServer>  

另請參閱