開啓IIS的WebGarden、WebFarm和StateServer之旅

前言                              php

  公司系統雖然配置有1臺NLB後拖4臺App Server最後搭一臺強勁無比的DB Server,但天天下午4點左右總被投訴系統慢,報表下載不了等問題。究其緣由,原來NLB採用鎖定sessionId轉發請求,而IIS的最大工做進程數倒是1而已,只能經過增長工做線程的方式來提升併發量,但增長線程會消耗更多內存,當所佔內存接近2G時應用48%左右的執行時間被分配給GC工做了,也就是說負載增大時上述硬件配置並然卵。那解決方案明顯以下:html

  1. NLB採用實際負載請求轉發請求;web

  2. IIS採用WebGarden模式;sql

  3. 多臺IIS組成WebFarm;緩存

  4. 爲實現IIS的WebGarden和WebFarm工做模式,須要配置啓用StateServer。服務器

  另外,因爲前期開發階段你們並不清楚採用IIS WebGarden模式運行所帶來的限制,所以還要對代碼進行分析、調整。cookie

  本文做爲上段時間工做內容時查閱資料的整理總結,以便往後查閱。session

 

何爲WebGarden & WebFarm?                併發

  IIS默認配置下采用的是單工做進程的工做模式,也就是隻啓用一個w3wp.exe進程處理全部請求,而後進程內啓用多個線程來處理併發請求,最大工做線程數由具體的操做系統和IIS來決定,當併發量大於線程數時則會讓請求排隊等待處理。這是面對高併發量,且部分請求處理耗時較長時就會形成大部分請求長期處於掛起的狀態,用戶感知就是慢,TMD慢。。。。app

  WebGarden其實就是IIS的多工做進程的工做模式,而WebFarm則是多臺IIS應用服務器做負載均衡。

  默認狀況下(No WebGarden, No WebFarm):

  WebGarden:

  

  WebFarm:

  

  配置WebGarden

    在IIS 6中,右鍵單擊「應用程序池」 > 「屬性」 > 轉到「性能」選項卡。在「性能」選項卡部分,有一個「Web Garden」的選項,默認值爲「1」,您能夠將該值設置爲您須要的數值。

    

    在IIS 7中,右鍵單擊「應用程序池」 > 轉到「高級設置」 > 找到「進程模型」,下面有個「最大工做進程」項。

    

    開啓WebGarden是否是很簡單呢?那問題落在到底maxWorkerProcesses設置多少才適合呢?通常建議設置爲「邏輯核數」便可。

  到底WebGarden針對哪一種場景,又有什麼好處呢?

    對於上述的問題,我想前IIS PM Chris Adams給出的答案會更準確(http://blogs.iis.net/chrisad/1342059

Web gardens was designed for one single reason – Offering applications that are not CPU-bound but execute long running requests the ability to scale and not use up all threads available in the worker process.

     從Chris Adams處咱們可知WebGarden的目的是針對大量長連接的情景,經過增長工做進程來增長可用的工做線程。

    另外,我想你們都有過這樣的經歷。maximum worker processes爲1時,併發量上揚時w3wp.exe所佔的內存(專用工做集/專用字節)會急速上升,當所佔內存接近2GB時響應延時就變得十分嚴重,惟一的辦法就是等待、等待、等待。。。。。。要不就回收進程釋放內存,但這時會中斷用戶的請求。

    那爲何會這樣呢?

    1. 首先須要明確的是 工做線程 對應 請求 是一一對應的,所以當接收到N個請求時,就會開啓N個工做線程處理請求,若請求量超過最大工做線程數時則會讓請求排隊;

    2. 線程自己也佔內存資源,就線程棧空間而言,IIS5/6每一個線程棧空間就佔256KB,而Windows Server 2000下則佔1MB。對於Windows Server 2008下的IIS7而言,32bit則佔256KB,64bit則佔512KB。極端狀況下即便新開的線程所處理的程序入參和局部變量只使用1KB,但線程棧依然會佔512KB。更不用說程序中還用到大量堆空間的對象了;

    3. 進程是分配內存資源的最小單位,也就全部工做線程均使用同一塊內存空間,更重要的是全部工做線程採用同一套GC機制,那麼當執行GC時將掛起全部工做線程;

    4. 雖然Windows Server2008 64Bit對進程所佔的內存空間沒有設置上限,但若進程所佔內存空間大且託管堆中含大量一次性對象那麼必然會引發頻繁的GC操做。(極端狀況下GC佔進程的執行時間片的48%左右)

    也就是咱們經過「任務管理器」查看w3wp.exe內存佔用率升高時,響應延時增大的根本緣由是:工做進程中託管堆存在大量臨時對象,致使頻繁執行GC操做,而GC操做執行時會掛起全部工做線程,致使請求處理的延時增大。

    而WebGarden就是將工做線程均勻分配到多個工做進程中,那麼各工做進程所佔用的內存相對較少,減小GC操做和每次GC執行的時間,而且即便執行GC操做也不會掛起全部工做線程,從而提供併發處理量。

 

StateServer配置流程                      

    配置WebGarden和WebFarm後,每一個請求將由不一樣的工做進程或應用服務器處理,那麼以前保存在工做進程所佔內存中的SessionTable和緩存信息將沒法共享。最明顯的例子就是經過將用戶的登錄信息保存在SesisonTable中,當啓用WebGarden時,用戶不定時被告知須要從新登錄。這是因爲請求被分配到另外一個工做進程處理,而該工做進程沒有對應的SessionTable記錄。

  這時咱們須要配置一臺獨立共享的StateServer來保存Sessoin等信息的服務器。

  對於WebGarden:

  

   對於WebFarm:

  

  下面咱們一步步配置吧!

   1. 服務器配置

       1). 安裝ASP.NET State Service組件:控制面板->程序和功能->打開或關閉Windows功能->Internet信息服務->萬維網服務->應用程序開發功能->ASP.NET

       2). 在「運行」面板上輸入regedit進入註冊表,進入HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/aspnet_state/Parameters

            修改AllowRemoteConnection,用於配置可被遠程連接的連接數,0表示僅能本機連接;

            修改Port,用於配置State Service的端口號,通常採用默認42424便可。

   3). 啓動/重啓State Service:計算機->管理->服務->ASP.NET State Service 啓用,自動。

   2. Web.config配置

       配置位於<system.web>下的<sessionState>節點

複製代碼
 <!--Session 配置。Session 爲請求的當前上下文保存用戶配置,每一個用戶獨立。不建議存放大量數據。
        mode: 
          Off: 設置爲不使用Session功能
          InProc: 默認值,在 IIS 進程中保存 Session,無存儲類型、大小限制,性能高,但容易丟失。
          StateServer:在 Windows 服務進程中保存 Session,序列化存儲,無大小限制,不依賴 Web 服務器,不容易丟失,但序列化消耗 CPU 性能。
          SQLServer:在 SQL Server 中保存 Session,序列化存儲,無大小限制,不依賴 Web 服務器,不容易丟失,但序列化消耗 CPU 性能。
          Custom:
        cookieless:
          true 使用Cookieless模式;這時客戶端的Session信息就再也不使用Cookie存儲了,而是將其經過URL存儲。好比網址爲http://localhost/MyTestApplication/(ulqsek45heu3ic2a5zgdl245)/default.aspx
          false 使用Cookie模式,這是默認值。
        timeout 
          設置通過多少分鐘後服務器自動放棄Session信息。默認爲20分鐘。
        stateConnectionString 
          設置將 Session 信息存儲在狀態服務中時使用的服務器名稱和端口號,例如:"tcpip=127.0.0.1:42424」。當mode的值是StateServer是,這個屬性是必需的。(42424是默認端口)。
        sqlConnectionString 
          設置與 SQL Server 鏈接時的鏈接字符串。例如 "data source=localhost;Integrated Security=SSPI;Initial Catalog=northwind"。當mode的值是SQLServer時,這個屬性是必需的。
        stateNetworkTimeout 
          設置當使用 StateServer 模式存儲 Session 狀態時,通過多少秒空閒後,斷開Web服務器與存儲狀態信息的服務器的 TCP/IP 鏈接的。默認值是10秒鐘。-->
<sessionState mode="Off|InProc|StateServer|SQLServer"
   cookieless="true|false"
   timeout="number of minutes"
   stateConnectionString="tcpip=server:port"
   sqlConnectionString="sql connection string"
   stateNetworkTimeout="number of seconds"
  /> 
複製代碼

 示例:<sessionState mode="StateServer" stateConnectionString="tcpip=localhost:42424" timeout="2880" />

 對於沒有啓用WebFarm而言,上述StateServer配置已經可OK了。但假若啓用WebFarm,那還要配置如下兩項:

 1. 配置MachineKey

   machineKey做爲加密/解密祕鑰。負載均衡時必須配置,不然會報「沒法驗證的錯誤」之類的問題。

     默認狀況下ASP.NET會自動生成一組machineKey,但做負載均衡時各臺應用服務器所生成的均不一樣,則會致使沒法正確加密解密共享信息。

<machineKey validationKey="86B6275BA31D3D713E41388692FCA68F7D20269411345AA1C17A7386DACC9C46E7CE5F97F556F3CF0A07159659E2706B77731779D2DA4B53BC47BFFD4FD48A54" decryptionKey="9421E53E196BB56DB11B9C25197A2AD470638EFBC604AC74CD29DBBCF79D6046" validation="SHA1" decryption="AES"/> 

    machineKey的生成函數

複製代碼
生成machineKey:

public static string CreateKey(int len)
{
byte[] bytes = new byte[len];
new RNGCryptoServiceProvider(). GetBytes(bytes);
StringBuilder sb = new StringBuilder();
for(int i = 0; i < bytes. Length; i++)
      {
sb. Append(string. Format("{0:X2}",bytes[i]));
      }
return sb. ToString();
}


使用:

validationKey = CreateKey(20);
decryptionKey = CreateKey(24);
複製代碼

  2. 配置AppID

   StateServer中Session信息的ID其實是由AppID和用戶的SessionID組成,所以若部署在多臺應用服務器上的網站的AppID不一樣,則會致使Session信息丟失的問題。

   IIS7下配置AppID

     

   IIS6下配置AppID

  方式1:在CMD下輸入 cd c:\Inetpub\AdminScripts 

                而後輸入 cscript adsutil.vbs move w3svc/999 w3svc/2 意思是將AppID從999改成2。

      方式2:修改MetaBase.xml文件。

 

Q&A                            

  Q:爲什麼我按照上述內容配置WebGarden和StateServer,但偶然間會報以下錯誤呢?

   A:因爲存放複雜的自定義結構體到SessionTable了,在作反序列化時報錯了。建議只存放String、Int32等簡單類型的數值到SessionTable,而後以它們爲鍵再在程序中獲取其它屬性。

 

注:

1.全文摘抄自:https://www.cnblogs.com/fsjohnhuang/p/5244785.html

2.文中涉及到線程池知識,能夠參見:http://www.learncsharptutorial.com/threadpooling-csharp-example.php

3.iis webfarm模式:

相關文章
相關標籤/搜索