asp.net Server Load Balancer

來源:互聯網
上載者:User

http://blog.csdn.net/lvlingwy/archive/2008/05/08/2418673.aspx

 http://bbs.ibeifeng.com/simple/index.php?t16926.html

 轉自:http://sai5d.blog.sohu.com/131936651.html

在WEB場中,動態網頁往往會因為幾台主機做了負載而產生SESSION丟失的問題,網上也有很多的介紹,我這裡只將我經曆的過程給大家分享一下:
系統要運行在Server Load Balancer的 Web 場環境中,而系統設定檔web.config中的Session狀態卻設定為InProc(即在本機存放區工作階段狀態),導至在使用者訪問量大 時,Session常經逾時的情況。引起這個現象的原因主要是因為使用者通過Server Load BalancerIP來訪問WEB應用系統,某段時候在某台伺服器儲存了Session 的工作階段狀態,但在其它的WEB前端伺服器中卻沒有儲存Session的工作階段狀態,而隨著並發量的增大,Server Load Balancer會當作路由隨時訪問閒置伺服器,結果空閑 的伺服器並沒有之前儲存的Session工作階段狀態。
解決辦法:
1.當您在Server Load Balancer的 Web 場環境中運行 ASP.NET Web 應用程式時,一定要使用 SqlServer 或 StateServer 工作階段狀態模式,在項目中我們基於效能考慮並沒有選擇SqlServer模式來儲存Session狀態,而是選擇一台SessionStateServer 伺服器來使用者的Session工作階段狀態。我們要在系統設定檔web.config中設定如下:
<sessionState mode="StateServer" cookieless="false" timeout="240" stateConnectionString="tcpip=192.168.0.1:42424" stateNetworkTimeout="14400" />
這裡的紅字型的IP一定要是同域的一台機器,在這台機器上進行第二步的操作,同時將其註冊表中HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Servi ces\aspnet_state\Parameter
s\AllowRemoteConnection的索引值改為1,然後重啟原生ASP.NET State Service服務
還要添加一項
<machineKey validationKey="78AE3850338BFADCE59D8DDF58C9E4518E7510149C46142D7AAD7F1AD49D95D4" decryptionKey="5FC88DFC24EA123C" validation="SHA1"/>
如何產生machineKey?
按照MSDN的標準說法:“對密鑰進行配置,以便將其用於對 Forms 身分識別驗證 Cookie 資料和檢視狀態資料進行加密和解密,並將其用於對進程外工作階段狀態標識進行驗證。”也就是說Asp.Net的很多加密,都是依賴於machineKey裡面的值,例如Forms 身分識別驗證 Cookie、ViewState的加密。預設情況下,Asp.Net的配置是自己動態產生,如果單台伺服器當然沒問題,但是如果多台伺服器負載平衡,machineKey還採用動態產生的方式,每台伺服器上的machinekey值不一致,就導致加密出來的結果也不一致,不能共用驗證和ViewState,所以對於多台伺服器負載平衡的情況,一定要在每台網站配置相同的machineKey。
machineKey產生的演算法:
validationKey = CreateKey(20);
decryptionKey = CreateKey(24);
     protected 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();
     }
附參考的matchineKey配置:
<?xml version="1.0"?>
<configuration>
<system.web>
     <machineKey validationKey="3FF1E929BC0534950B0920A7B59FA698BD02DFE8" decryptionKey="280450BB36319B474C996B506A95AEDF9B51211B1D2B7A77" decryption="3DES" validation="SHA1"/>
     </system.web>
</configuration>

2. 我們同時還要在SessionStateServer 伺服器中啟動ASP.NET State Service服務,具體設定:控制台>>管理工具>>服務>>ASP.NET State Service,把它設為自動啟動即可。
3. 每台前端WEB服務的Microsoft“Internet 資訊服務”(IIS)設定
             要在 Web 場中的不同 Web 服務器間維護工作階段狀態,Microsoft“Internet 資訊服務”(IIS) 設定資料庫中 Web 網站的應用程式路徑(例如,\LM\W3SVC\2)與 Web 場中所有 Web 服務器必須相同。大小寫也必須相同,因為應用程式路徑是區分大小寫。在一台 Web 服務器上,承載 ASP.NET 應用程式的 Web 網站的執行個體 ID 可能是 2(其中應用程式路徑是 \LM\W3SVC\2)。在另一台 Web 服務器上,Web 網站的執行個體 ID 可能是 3(其中應用程式路徑是 \LM\W3SVC\3)。因此,Web 場中的 Web 服務器之間的應用程式路徑是不同的。我們必須使Web 場Web 網站的執行個體 ID 相同即可。你可以在IIS中把某一個WEB配置資訊儲存為一個檔案,其他Web 服務器的IIS配置可以來自這一個檔案。您如果想知道具體的設定請訪問Microsoft Support網站:http://support.microsoft.com/default.aspx?scid=kb;zh-cn;325056
補充一些相關資料:
PRB: Session Variables Are Lost If You Use FRAMESET in Internet Explorer 6.0
http://support.microsoft.com/kb/323752/EN-US/#
PRB: Session Data Is Lost When You Use ASP.NET InProc Session State Mode
http://support.microsoft.com/?id=324772
PRB:如果您使用 SqlServer 或 StateServer 會話模式 Web 場中會丟失工作階段狀態
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;325056

ASP.NET Session State FAQ
http://www.eggheadcafe.com/articles/20021016.asp

參考來自:http://hi.baidu.com/panshuaiyang

應用程式如何用兩種方式儲存Session資訊
以下的各種操作主要是針對這一段配置展開。讓我們先看看這一段配置中所包含的內容的意思。sessionState節點的文法是這樣的:

<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"
/>

必須有的屬性是

屬性 選項 描述
mode 設定將Session資訊儲存到哪裡
Off 設定為不使用Session功能
InProc 設定為將Session儲存在進程內,就是ASP中的儲存方式,這是預設值。
StateServer 設定為將Session儲存在獨立的狀態服務中。
SQLServer 設定將Session儲存在SQL Server中。

可選的屬性是:

屬性 選項 描述
cookieless 設定用戶端的Session資訊儲存到哪裡
ture 使用Cookieless模式
false 使用Cookie模式,這是預設值。
timeout 設定經過多少分鐘後伺服器自動放棄Session資訊。預設為20分鐘
stateConnectionString 設定將Session資訊儲存在狀態服務中時使用的伺服器名稱和連接埠號碼,例如:"tcpip=127.0.0.1:42424”。當mode的值是StateServer是,這個屬性是必需的。
sqlConnectionString 設定與SQL Server串連時的連接字串。例如"data source=localhost;Integrated Security=SSPI;Initial Catalog=northwind"。當mode的值是SQLServer時,這個屬性是必需的。
stateNetworkTimeout 設定當使用StateServer模式儲存Session狀態時,經過多少秒空閑後,斷開Web伺服器與儲存狀態資訊的伺服器的TCP/IP串連的。預設值是10秒鐘。
ASP.NET中用戶端Session狀態的儲存
在我們上面的Session模型簡介中,大家可以發現Session狀態應該儲存在兩個地方,分別是用戶端和伺服器端。用戶端只負責儲存相應網站的 SessionID,而其他的Session資訊則儲存在伺服器端。在ASP中,用戶端的SessionID實際是以Cookie的形式儲存的。如果使用者 在瀏覽器的設定中選擇了禁用Cookie,那末他也就無法享受Session的便利之處了,甚至造成不能訪問某些網站。為瞭解決以上問題,在 ASP.NET中用戶端的Session資訊儲存方式分為:Cookie和Cookieless兩種。

ASP.NET中,預設狀態下,在用戶端還是使用Cookie儲存Session資訊的。如果我們想在用戶端使用Cookieless的方式儲存Session資訊的方法如下:

找到當前Web應用程式的根目錄,開啟Web.Config檔案,找到如下段落:

<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
cookieless="false"
timeout="20"
/>

這段話中的cookieless="false"改為:cookieless="true",這樣,用戶端的Session資訊就不再使用 Cookie儲存了,而是將其通過URL儲存。關閉當前的IE,開啟一個新IE,重新訪問剛才的Web應用程式,就會看到類似下面的樣子:

其中,http://localhost/MyTestApplication/(ulqsek45heu3ic2a5zgdl245) /default.aspx中黑體標出的就是用戶端的Session ID。注意,這段資訊是由IIS自動加上的,不會影響以前正常的串連。

ASP.NET中伺服器端Session狀態的儲存
準備工作

為了您能更好的體驗到實驗現象,您可以建立一個叫做SessionState.aspx的頁面,然後把以下這些代碼添加到<body></body>中。

<scriptrunat="server">
Sub Session_Add(sender As Object, e As EventArgs)
Session("MySession") = text1.Value
span1.InnerHtml = "Session data updated! <P>Your session contains: <font color=red>" & \
Session("MySession").ToString() & "</font>"
End Sub

Sub CheckSession(sender As Object, eAs EventArgs)
If (Session("MySession")Is Nothing) Then
span1.InnerHtml = "NOTHING, SESSION DATA LOST!"
Else
span1.InnerHtml = "Your session contains: <font color=red>" & \
Session("MySession").ToString() & "</font>"
End If
End Sub
</script>
<formrunat="server"id="Form2">
<inputid="text1"type="text"runat="server"name="text1">
<inputtype="submit"runat="server"OnServerClick="Session_Add"
value="Add to Session State" id="Submit1"name="Submit1">
<inputtype="submit"runat="server"OnServerClick="CheckSession"
value="View Session State" id="Submit2"name="Submit2">
</form>
<hrsize="1">
<fontsize="6"><spanid="span1"runat="server" /></font>

這個SessionState.aspx的頁面可以用來測試在當前的伺服器上是否丟失了Session資訊。

將伺服器Session資訊儲存在進程中
讓我們來回到Web.config檔案的剛才那段段落中:

<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
cookieless="false"
timeout="20"
/>
當mode的值是InProc時,說明伺服器正在使用這種模式。

這種方式和以前ASP中的模式一樣,就是伺服器將Session資訊儲存在IIS進程中。當IIS關閉、重起後,這些資訊都會丟失。但是這種模式也有自己 最大好處,就是效能最高。應為所有的Session資訊都儲存在了IIS的進程中,所以IIS能夠很快的訪問到這些資訊,這種模式的效能比進程外儲存 Session資訊或是在SQL Server中儲存Session資訊都要快上很多。這種模式也是ASP.NET的預設。  
好了,現在讓我們做個實驗。開啟剛才的SessionState.aspx頁面,隨便輸入一些字元,使其儲存在 Session中。然後,讓我們讓IIS重起。注意,並不是使當前的網站停止再開始,而是在IIS中原生機器名的節點上點擊滑鼠右鍵,選擇重新啟動 IIS。(想當初使用NT4時,重新啟動IIS必須要重新啟動電腦才行,微軟真是@#$%^&)返回到SessionState.aspx頁面 中,檢查剛才的Session資訊,發現資訊已經丟失了。

將伺服器Session資訊儲存在進程外
首先,讓我們來開啟管理工具->服務,找到名為:ASP.NET State Service的服務,啟動它。實際上,這個服務就是啟動一個要儲存Session資訊的進程。啟動這個服務後,你可以從Windows工作管理員 ->進程中看到一個名為aspnet_state.exe的進程,這個就是我們儲存Session資訊的進程。

然後,回到Web.config檔案中上述的段落中,將mode的值改為StateServer。儲存檔案後的重新開啟一個IE,開啟 SessionState.aspx頁面,儲存一些資訊到Session中。這時,讓我們重起IIS,再回到SessionState.aspx頁面中查 看剛才的Session資訊,發現沒有丟失。

實際上,這種將Session資訊儲存在進程外的方式不光指可以將資訊儲存在原生進程外,還可以將Session資訊儲存在其他的伺服器的進程中。這 時,不光需要將mode的值改為StateServer,還需要在stateConnectionString中配置相應的參數。例如你的計算你是 192.168.0.1,你想把Session儲存在IP為192.168.0.2的電腦的進程中,就需要設定成這 樣:stateConnectionString="tcpip=192.168.0.2:42424"。當然,不要忘記在192.168.0.2的計算 機中裝上.NET Framework,並且啟動ASP.NET State Services服務。

將伺服器Session資訊儲存在SQL Server中
首先,還是讓我們來做一些準備工作。啟動SQL Server和SQL Server代理服務。在SQL Server中執行一個叫做InstallSqlState.sql的指令檔。這個指令檔將在SQL Server中建立一個用來專門儲存Session資訊的資料庫,及一個維護Session資訊資料庫的SQL Server代理作業。我們可以在以下路徑中找到那個檔案:

[system drive]\winnt\Microsoft.NET\Framework\[version]\
然後開啟查詢分析器,串連到SQL Server伺服器,開啟剛才的那個檔案並且執行。稍等片刻,資料庫及作業就建立好了。這時,你可以開啟企業管理器,看到新增了一個叫ASPState的 資料庫。但是這個資料庫中只是些預存程序,沒有使用者表。實際上Session資訊是儲存在了tempdb資料庫的 ASPStateTempSessions表中的,另外一個ASPStateTempApplications表格儲存體了ASP中Application 對象資訊。這兩個表也是剛才的那個指令碼建立的。另外查看管理->SQL Server代理->作業,發現也多了一個叫做ASPState_Job_DeleteExpiredSessions的作業,這個作業實際上就是 每分鐘去ASPStateTempSessions表中刪除到期的Session資訊的。

接著,我們返回到Web.config檔案,修改mode的值改為SQLServer。注意,還要同時修改sqlConnectionString的值,格式為:

sqlConnectionString="data source=localhost; Integrated Security=SSPI;"
其中data source是指SQL Server伺服器的IP地址,如果SQL Server與IIS是一台機子,寫127.0.0.1就行了。Integrated Security=SSPI的意思是使用Windows整合身分識別驗證,這樣,訪問資料庫將以ASP.NET的身份進行,通過如此配置,能夠獲得比使用 userid=sa;password=口令的SQL Server驗證方式更好的安全性。當然,如果SQL Server運行於另一台電腦上,你可能會需要通過Active Directory域的方式來維護兩邊驗證的一致性。

同樣,讓我們做個實驗。向SessionState.aspx中添加Session資訊,這時發現Session資訊已經存在SQL Server中了,即使你重起電腦,剛才的Session資訊也不會丟失。現在,你已經完全看見了Session資訊到底是什麼樣子的了,而且又是儲存 在SQL Server中的,能幹什麼就看你的發揮了,哈哈。

總結
通過這篇文章,你可以看到在Session的管理和維護上,ASP.NET比ASP有了很大的進步,我們可以更加隨意的挑選適合的方法了。對於企業級的應 用來說,這無疑對於伺服器的同步、伺服器的穩定性、可靠性都是有利的。相信在強大的微軟支援下,新一代的電子商務平台將會搭建的更好!
來自:http://topic.csdn.net/t/20050314/17/3850093.html

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.