转:asp.net 负载平衡-Session相关
生活随笔
收集整理的這篇文章主要介紹了
转:asp.net 负载平衡-Session相关
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
來自:http://www.cnblogs.com/zxylonely/archive/2009/12/23/1630197.html
?
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丟失的問題,網上也有很多的介紹,我這里只將我經歷的過程給大家分享一下:系統要運行在負載平衡的 Web 場環境中,而系統配置文件web.config中的Session狀態卻設置為InProc(即在本地存儲會話狀態),導至在用戶訪問量大 時,Session常經超時的情況。引起這個現象的原因主要是因為用戶通過負載平衡IP來訪問WEB應用系統,某段時候在某臺服務器保存了Session 的會話狀態,但在其它的WEB前端服務器中卻沒有保存Session的會話狀態,而隨著并發量的增大,負載平衡會當作路由隨時訪問空閑的服務器,結果空閑 的服務器并沒有之前保存的Session會話狀態。
解決辦法:?
1.當您在負載平衡的 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
轉載于:https://www.cnblogs.com/songsh96/archive/2010/10/27/1862136.html
總結
以上是生活随笔為你收集整理的转:asp.net 负载平衡-Session相关的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图解一步步安装SharePoint Fo
- 下一篇: 在程序员的道路上,义无反顾的努力,有思想