Session對象用于存儲從一個用戶開始訪問某個特定的aspx的頁面起,到用戶離開為止,特定的用戶會話所需要的信息。用戶在應用程序的頁面切換時,Session對象的變量不會被清除。
對于一個Web應用程序而言,所有用戶訪問到的Application對象的內(nèi)容是完全一樣的;而不同用戶會話訪問到的Session對象的內(nèi)容則各不相同。 Session可以保存變量,該變量只能供一個用戶使用,也就是說,每一個網(wǎng)頁瀏覽者都有自己的Session對象變量,即Session對象具有唯一性。
最近這兩天被一個Web Farm環(huán)境下的Session處理問題虐得很痛苦,這是一個ASP.NETSession基礎知識的一個合集,有的地方感覺是有重復,比較啰嗦,我基本上按照原文將他翻譯出來了,小弟程序水平不高,英語水平更差(09年高考英語65分,滿分150),自我感覺Session基礎內(nèi)容是講清楚了,我粗淺的理解下,沒有發(fā)現(xiàn)有什么錯誤了,文章較淺,請各位發(fā)現(xiàn)有什么不對的地方告訴我,我一定盡快處理,這篇文章很適合初學者看,作者說的很清楚,能把ASP.NET下Session的玩法看得較為清晰。另外我會在我另一篇博文中將我所遇到的問題以及解決辦法和大家共享。原文地址:http://www.codeproject.com/Articles/32545/Exploring-Session-in-ASP-Net
這篇文章將使你非常好地理解Session,在這篇文章中,我會包含Session的基礎知識,用不同的方式儲存Session對象,包含Web園(Web Farm)和Web農(nóng)場(Web Garden)以及負載均衡等等情境。我也將詳細闡明Session在實際生產(chǎn)環(huán)境中的應用。希望您能喜歡這篇文章,歡迎您反饋您的看法和建議。
什么是Session
Web是無狀態(tài)的,他提供了一種新的方式:每次都通過用戶對服務器提交請求而渲染新的網(wǎng)頁。眾所周知,HTTP是一種無狀態(tài)協(xié)議,他不能通過頁面和客戶端保持連接。如果用戶需要增加一些信息和跳轉(zhuǎn)到了另外的頁面,原有的數(shù)據(jù)將會丟失,用戶將無法恢復這些信息。我們需要這玩意兒干嘛呢?我們需要保存信息!Session提供了一個在服務器端保存信息的方案。他能支持任何類型對象和用戶對象信息作為對象保存起來。Session為每一個客戶端都獨立地保存,這意味著Session數(shù)據(jù)存儲著每個客戶端的基礎信息。請看下圖:
每一個客戶端都有一份獨立的Session
用Session進行狀態(tài)管理是ASP.NET最好的特性之一,因為它是安全的,對于客戶端是透明的,并且他能存儲任何類型的對象。而在這些優(yōu)點之外,有時Session會導致一些對性能要求較高的網(wǎng)站的性能問題。因為他消耗服務器的內(nèi)存存儲用戶訪問網(wǎng)站所需的數(shù)據(jù),現(xiàn)在讓我們來看一看Session對于您Web 應用的利弊。
Session的利弊
接下來我們討論普通情況下使用Session的利弊,我會描述每一種Session的使用情境。
優(yōu)點:
他能在整個應用中幫助維護用戶狀態(tài)和數(shù)據(jù)。
他能讓我們簡單地實現(xiàn)存儲任何類型的對象。
獨立地保存客戶端數(shù)據(jù)。
對于用戶來說,Session是安全的、透明的。
缺點:
因為Session使用的是服務器的內(nèi)存,所以在用戶量大的時候會成為性能瓶頸。
在序列化和反序列化的過程中他也會成為性能瓶頸,因為在StateServer(狀態(tài)服務)模式和SQL Server模式下我們需要對我們存儲的數(shù)據(jù)進行序列化和反序列化我們所存儲的數(shù)據(jù)。
除此之外,Session的各種模式都有其利弊。接下來我們將討論各種Session模式。
對Session進行讀/寫
讀/寫Session是非常簡單的,就像使用ViewState一樣,我們能使用System.Web.SessionState.HttpSessionState這個類來與Session進行交互,這個類在ASP.NET頁面內(nèi)內(nèi)建(提供)了Session。下面的代碼就是使用Session進行存儲的例子:
//Storing UserName in Session Session["UserName"] = txtUser.Text;
接下來讓我們來看如何從Session讀取數(shù)據(jù):
//Check weather session variable null or not if (Session["UserName"] != null) { //Retrieving UserName from Session lblWelcome.Text = "Welcome : " + Session["UserName"]; } else { //Do Something else }
我們也能存儲其他對象,下面的例子展示了如何存儲一個DataSet到Session里
//Storing dataset on Session Session["DataSet"] = _objDataSet;
下面的代碼展示了如何從Session內(nèi)讀取DataSet
//Check weather session variable null or not if (Session["DataSet"] != null) { //Retrieving UserName from Session DataSet _MyDs = (DataSet)Session["DataSet"]; } else { //Do Something else }
參考文獻:
MSDN (read the session variable section)
Session ID
ASP.NET使用了120bit的標識符用以標識每個Session。這是足夠安全的、不可逆的設計。當客戶端和服務端進行通信的時候,在他們之間需要傳輸這個Session ID,當客戶端發(fā)送request(請求)數(shù)據(jù)時,ASP.NET搜索Session ID,通過Session ID檢索數(shù)據(jù)。這個過程通過以下步驟進行:
客戶端點擊網(wǎng)站->客戶端信息被Session儲存
服務端為客戶端創(chuàng)建一個唯一的Session ID,并在服務端存儲這個ID
客戶端通過發(fā)送帶有SessionID的請求以獲取在服務端保存的信息
服務器端通過Session Provider從狀態(tài)服務(State Server)中獲取序列化后的數(shù)據(jù)并且進行類型強制轉(zhuǎn)換成對象
以下為流程圖片:
客戶端、Web服務器、Session Provider的通信
參考文獻:
SessionID in MSDN
Session模式和Session Provider
在ASP.NET中,有以下幾種Session模式可以使用
InProc
StateServer
SQLServer
Custom
每一種Session State都有一種Session Provider。以下的圖形將展示他們的關(guān)系:
Session state體系圖
我們能在這些基礎的Session State Provider中進行選擇。當ASP.NET接收到帶有Session ID的信息請求時Session State和他相應的Provider負責提供和存儲對應的信息。下面的表展示了Session 模式以及Provider的名稱:
Session State模式 | State Provider |
InProc | In-memory object(內(nèi)置對象) |
StateServer | Aspnet_state.exe |
SQLServer | SQL Server Database |
Custom | Custom provider |
除此之外,還有另一個模式:“OFF”,如果我們選擇這個選項,Session將不能為這個應用提供服務。但是我們的目標是使用Session,所以我們將討論上面四種的Session模式。
Session States
Session State模式基本上可以認為把所有的Session配置、維護都交給了Web應用。Session State他本身就是一個大東西,他基本上意味著你所有關(guān)于Session 的配置無論實在web.config或者頁面后端代碼。在web.config里
Session事件
在ASP.NET中有兩個可以使用的Session事件:
Session_Start
Session_End
你能處理應用中的這兩個事件在global.asax這個文件里,當一個新的Session開啟時session_start事件被觸發(fā),當Session被回收或是過期時Session_End被觸發(fā):
void Session_Start(object sender, EventArgs e) { // Code that runs when a new session is started } void Session_End(object sender, EventArgs e) { // Code that runs when a session ends. }
參考文獻:
Application and Session Events
Session 模式
我們已經(jīng)討論過Session模式,接下來說說這些模式的不同:
Off
InProc
StateServer
SQLServer
Custom
如果我們在web.config內(nèi)設定Session Mode="off",Session將在應用中不可用,他的設置是這樣的:
InProc Session 模式:
這是ASP.NET默認的Session模式,他在當前的應用程序域中存儲Session信息。這是性能最好的Session模式。但是他最大的缺點在于:當我們重啟服務的時候Session數(shù)據(jù)將會丟失。InProc模式有一些優(yōu)缺點,接下來我們將詳細這些點。
InProc概述:
我們已經(jīng)說過,InProc模式Session數(shù)據(jù)將會儲存在當前應用程序域中,所以他是最簡單、快速、好用的。
InProc模式Session數(shù)據(jù)保存在應用程序域內(nèi)的一個集合對象,他在一個應用程序池中進行工作,如果我們重啟服務,我們將丟失Session數(shù)據(jù)。正常情況下客戶端發(fā)送請求,State Provider從內(nèi)存對象中讀取數(shù)據(jù)并返回給客戶端,在web.config中我們必須提供Session模式和設置過期時間:
上面的設置中,設置了Session的過期時間為30分鐘,這也可以從后臺代碼中進行配置。
Session.TimeOut=30;
在ASP.NET中有兩個Session事件可以進行使用:Session_Start()和Session_End()而這種模式(后端代碼控制)只支持Session_End()事件。這個事件在Session超時時被調(diào)用,一般情況下,InProc Session模式是這樣的:
當Session過期時Session_End()事件被調(diào)用。InProc是一個非?斓奶幚頇C制,因為沒有序列化地讀/寫過程,并且數(shù)據(jù)保存在相同的域內(nèi)。
什么時候我們使用InProc模式呢?
InProc是默認的Session模式,他對小型應用程序和用戶量比較小的程序非常合適,我們應盡量避免在Web園(Web Garden)和Web農(nóng)場(Web Farm)情境下使用他(以后我會講到這個情境)
優(yōu)缺點:
優(yōu)點:
他把Session數(shù)據(jù)存儲在當前應用程序域內(nèi),所以訪問數(shù)據(jù)會非常的快速、簡單、高效。
在InProc模式中不需要對對象進行序列化存儲。
使用起來非常簡單,就像ViewState一樣。
缺點:
雖然InProc是最快的,最通用的,也是默認的機制,但是他有許多限制:
如果工作的應用進程被回收,Session數(shù)據(jù)將全部丟失。
雖然他是最快的,但是當Session數(shù)據(jù)太大和用戶過多時,他會由于內(nèi)存的大量使用而影響整個程序的性能。
我們不能在Web園環(huán)境中使用這種模式。
這種模式不適合用于Web農(nóng)場(Web Farm)環(huán)境中。
現(xiàn)在,我們來看看其他可用的方法來規(guī)避這些缺點,首先是StateServer模式:
StateServer Session模式
StateServer模式概述
這也叫做Out-Proc Session模式。StateServer使用了一個獨立的Windows服務來提供Session服務,他獨立于IIS,也能獨使用一臺服務器。StateServer的服務來自于aspnet_state.exe提供。這個服務也能和您的應用服務共同運行在同一臺服務器上,注意他是獨立于Web應用程序域的一個服務。這意味著你重啟你的Web服務后Session數(shù)據(jù)依然存在。這個方案的缺點在于有一個性能瓶頸:數(shù)據(jù)讀寫需要進行序列化和反序列化,因為不是同一個應用程序域,所以他也增加了數(shù)據(jù)讀寫的性能消耗,因為他們是兩個不同的進程。
配置StateServer Session模式
在StateServer模式里,Session數(shù)據(jù)存儲在獨立于IIS的一個服務里。這個進程作為一個Windows服務運行,你能在Windows服務管理器(MMC)或者命令行中進行啟動。
默認情況下,ASP.NET StateServer(中文名:ASP.NET狀態(tài)服務)默認情況下啟動方式是“手動”我們必須將他設置為自動。
如果從命令行啟動的化只需要輸入:"net start aspnet_state";默認情況下,這個服務監(jiān)聽TCP端口42424,但是我們可以在注冊表里改變這個設置,如圖:
現(xiàn)在,我們來看一看web.config對StateServer的設置,在StateServer的設置里我們需要指定StateServer連接字符串stateConnectionString:指向運行StateServer的系統(tǒng)。默認設置下,StateConnectionString使用IP127.0.0.1(localhost)端口使用42424。
當我們使用StateServer,我們還能設置超時stateNetworkTimeOut特性指定等待服務響應的秒數(shù),即發(fā)出請求到取消響應的事件時間間隔。默認情況下是10秒。
當使用StateServer進行存儲時對象將被序列化進行儲存,而讀取對象時,將對數(shù)據(jù)進行反序列化,我們來看下面的例子:
StateServer是如何工作的
我們使用StateServer來避免當重啟Web服務時無謂的Session數(shù)據(jù)丟失。StateServer是在aspnet_state.exe進程作為一個服務來進行維護的,這個進程維護著所有的Session數(shù)據(jù),但是在存儲到StateServer之前我們需要對數(shù)據(jù)進行序列化。
如上圖所示,客戶端發(fā)送請求到Web服務器,Web服務器將Session數(shù)據(jù)存儲在StateServer里,StateServer也許在當前的系統(tǒng)里,也可能在另一個系統(tǒng)里,但他一定是獨立于IIS的,為了實現(xiàn)他,我們必須在web.config里進行配置stateConnectionString。例如我們設置指向127.0.0.1:42424,這將把數(shù)據(jù)存儲在本地的系統(tǒng)內(nèi),為了實現(xiàn)改變StateServer指向的目的,我們改變了IP,并且確定aspnet_state.exe正常運行于這個系統(tǒng)上,接下來當你需要讀寫Session時(也就是通過修改IP來導致一個錯誤的指向),你就會引發(fā)下圖這樣的異常:
當我們存儲一個對象到Session,對象將被序列化。系統(tǒng)利用State Provider將數(shù)據(jù)存儲進StateServer。當讀取數(shù)據(jù)時,State Provider將返回數(shù)據(jù),完整的流程圖如下圖:
StateServer Session模式例子:
這是一個簡單的使用StateServer Session模式的例子,我直接在IIS里創(chuàng)建這個例子,能輕松地明白他的用法:
步驟1:打開Visual Studio>文件>新建>網(wǎng)站。選擇HTTP作為web應用的位置。
現(xiàn)在你打開IIS,你將會看到創(chuàng)建了一個虛擬目錄,名字是你的應用名,在我的例子中是StateServer。
步驟2:創(chuàng)建一個簡單的UI:他將獲取一個學生的角色編號和名字,我們將保存名字和編號到StateServer Session里。我也將創(chuàng)建一個類:StudentInfo,這個類的定義如下:
[Serializable] public class StudentInfo { //Default Constructor public StudentInfo() { } ////// Create object of student Class //////Int RollNumber ///String Name public StudentInfo(int intRoll, string strName) { this.Roll = intRoll; this.Name = strName; } private int intRoll; private string strName; public int Roll { get { return intRoll; } set { intRoll = value; } } public string Name { get { return strName; } set { strName = value; } } }
現(xiàn)在來看后端代碼,我增加了兩個Button:一個是保存Session,另一個是獲取Session:
protected void btnSubmit_Click(object sender, EventArgs e) { StudentInfo _objStudentInfo = new StudentInfo(Int32.Parse( txtRoll.Text) ,txtUserName.Text); Session["objStudentInfo"] = _objStudentInfo; ResetField(); } protected void btnRestore_Click(object sender, EventArgs e) { StudentInfo _objStudentInfo = (StudentInfo) Session["objStudentInfo"]; txtRoll.Text = _objStudentInfo.Roll.ToString(); txtUserName.Text = _objStudentInfo.Name; }
步驟3:配置你的web.config的StateServer,在之前介紹過,請確保web.config在配置所指向的服務器上的State Server是處于開啟并運行的狀態(tài)。
步驟4:運行應用。
輸入數(shù)據(jù),點擊Submit。
接下來的測試,我將完整的解釋如何使用StateServer
首先:移除StudentInfo類[Serializable]特性,然后運行應用。當你點解Submit按鈕,你將看到如下的錯誤:
清晰地指出了在存儲之前你必須序列化你的對象。
第二:運行程序,在點擊了Submit按鈕保存數(shù)據(jù)后,重啟IIS
如果在InProc中,我保證你的Session數(shù)據(jù)將會丟失,但是在StateServer中,點擊Restore Session按鈕,你將獲取你的原始數(shù)據(jù),因為StateServer數(shù)據(jù)不依賴于IIS,它獨立地保存數(shù)據(jù)。
第三:在Windows 服務管理程序(MMC)中停止StateServer服務,你再點擊Submit按鈕,你將看到如下錯誤:
因為你的StateServer進程沒有運行,所以當你在使用StateServer的時候,請牢記這三點。
優(yōu)點和缺點
基于上述討論:
優(yōu)點:
StateServer獨立于IIS運行,所以無論IIS出什么問題都影響不到StateServer的數(shù)據(jù)。
他能在Web Farm和Web Garden環(huán)境中使用。
缺點:
要進行序列化和反序列化,拖慢速度。
StateServer需要保證正常運行。
我在這里停止StateServer的講述,你將在負載均衡中看到他更多更有趣的點,Web Farm,Web Garden情境下。
參考文獻:
State Server Session Mode
ASP.NET Session State
SQL Server Session模式
SQL Server模式簡介
ASP.NET這個Session模式提供給我們了更強的安全性和可靠性,在這個模式下,Session數(shù)據(jù)被序列化并存儲到一個SQL Server的數(shù)據(jù)庫中,這個模式缺點在于Session需要序列化和反序列化的讀寫方式成為了主要的性能瓶頸,他是Web Farm的最佳選擇。
設置SQL Server,我們需要這些SQL腳本:
安裝:InstallSqlState.sql
卸載:UninstallSQLState.sql
最簡單的配置方式是利用aspnet_regsql命令。
之前已經(jīng)解釋過了如何配置,這是最有用的狀態(tài)管理方法在web Farm模式里。
我們?yōu)楹问褂肧QL Server模式?
SQL Server Session模式提供了更安全、更可靠的Session管理。
他保證了數(shù)據(jù)在一個集中式的環(huán)境中(數(shù)據(jù)庫)。
當我們需要更安全地實現(xiàn)Session時就應該使用SQL Server模式。
假如服務器經(jīng)常需要重啟,這是一個完美的解決方案。
這是一個完美解決web Farm和web園的方案(這個我將在后面詳細解釋)。
當我們需要在兩個應用間共享Session時我們需要使用SQL Server模式。
配置SQL Server Session模式
在SQL Server模式中,我們的數(shù)據(jù)保存在SQL Server中,所以我們首先要在web.config里提供數(shù)據(jù)庫連接字符串,sqlConnectionString是被用來做這事的。
在連接字符串配置完成后,我們將要配置SQL Server,我將在這里演示如何用aspnet_regsql命令進行數(shù)據(jù)庫配置。
第一步:進入命令行,進入到Framework version目錄E.g. :c:\windows\microsoft.net\framework\
第二步,帶參運行aspnet_regsql命令。
下面是參數(shù)的使用:
Parameters | Description |
-ssadd | 增加 SQLServer 模式 session state. |
-sstype p | P 持久化.將這些數(shù)據(jù)持久化存儲于數(shù)據(jù)庫中 |
-S | 服務器名 |
-U | 用戶名 |
-P | 密碼. |
運行結(jié)束后,你見看到如下的信息:
配置結(jié)束。
第三步:
打開SQL Server,查看數(shù)據(jù)庫ASPState庫,將有兩張表:
ASPStateTempApplications
ASPStateTempSessions
更改設置中的連接字符串,建立一個像StateServer例子中那樣的應用
點擊Submit時保存Roll Number和用戶名,打開數(shù)據(jù)庫,進入ASPStateTempSessions表,這是你保存的Session數(shù)據(jù):
現(xiàn)在我們再來討論以下StateServer模式中所討論的幾個問題:
1、從StydentInfo類中移除Serialize特性(keyword)
2、重啟IIS再讀取Session數(shù)據(jù)
3、停止SQL Server服務
我想這些問題我已經(jīng)在StateServer解釋得很清楚了。
(注:第一種將導致無法序列化對象,會拋出異常,第二種無影響,第三種,在關(guān)閉數(shù)據(jù)庫服務時會有影響,而重啟數(shù)據(jù)庫服務將找回Session內(nèi)的數(shù)據(jù),因為他是持久化儲存的。)
優(yōu)缺點
優(yōu)點:
Session數(shù)據(jù)不受IIS重啟的影響
最可靠和最安全的Session管理模式
他在本地中心化保存Session數(shù)據(jù),能使其他應用方便地進行訪問
在Web Farm 和Web Garden情境下非常實用
缺點:
和默認模式比較起來,會顯得很慢
對象的序列化和反序列化會成為性能瓶頸
因為需要在不同的服務器上訪問SQL Server,我們必須保證SQL Server的穩(wěn)定運行。
參考資料:
Read more about SQLServer mode
自定義Session模式
通常情況下,我們使用InProc模式、StateServer模式、SQL Server模式就夠了,可是我們還是需要了解一些用戶自定義Session模式的相關(guān)知識。這是一種相當有趣的Session模式,因為用戶的Session全部交由了我們進行控制,甚至Session ID,你都能通過自己寫算法來生成Session ID。
你能夠容易地從基類SessionStateStoreProviderBase開發(fā)出自定義的Provider,你也能通過實現(xiàn)ISessionIDManager接口來產(chǎn)生SessionID。
下圖是自定義方法的處理過程:
在Initialize方法中,我們能設置一個自定義Provider。他將提供給Provider初始化連接。SetItemExpireCallback被用作提供SessionTimeOut(Session過期),當Session過期時我們能注冊一個方法進行調(diào)用。InitializeRequest在請求發(fā)起的時候被調(diào)用,CreateNewStoreData在創(chuàng)建一個SessionStateStoreData(Session數(shù)據(jù)存儲類)實例時候被調(diào)用。
我們何時使用自定義Session模式?
1、 當我們想將Session數(shù)據(jù)存儲在SQL Server之外的數(shù)據(jù)庫內(nèi)時。
2、 當我們必須使用一個已存在的(特定的)表來存儲Session數(shù)據(jù)的時候。
3、 當我們需要使用自定義的SessionID的時候
如何配置自定義Session模式?
我們需要在web.config里進行這樣的配置:
如果你想了解更多的關(guān)于自定義模式的信息,請查閱參考資料。
優(yōu)缺點:
優(yōu)點:
1、 我們能使用一個已存在的表(指定的表)來存儲Session數(shù)據(jù)。當我們使用一個之前使用的數(shù)據(jù)庫時,這樣做是很有用的。
2、 他獨立于IIS運行,所以重啟服務器對他也沒有影響。
3、 我們能建立自己的Session ID邏輯來分配Session ID。
缺點:
1、 處理數(shù)據(jù)很慢。
2、 創(chuàng)建一個自定義的Session狀態(tài)Provider是一個基礎性(low-level)任務,他需要小心處理各種情況以及保證數(shù)據(jù)安全。
我推薦您使用第三方提供的Provider而不是自己寫一套Provider。
參考資料:
Custom Mode
生產(chǎn)部署的概述:
在實際的生產(chǎn)工作環(huán)境中部署我們的應用對于一個Web開發(fā)者來說是一個非常重大的挑戰(zhàn)。因為在大的生產(chǎn)環(huán)境中,有大量的用戶數(shù)據(jù)需要處理,數(shù)據(jù)量大到一臺服務器難以負載這么巨大的數(shù)據(jù)處理量。這個概念來自于Web Farm,Web Garden,負載均衡的使用。
在幾個月前,我部署了一個實際環(huán)境:這個環(huán)境要處理百萬級的用戶訪問以及超過10個域控制器,通過負載均衡搭載了超過10臺服務器和服務數(shù)據(jù)庫。例如交易服務器、LCS服務器。最大的挑戰(zhàn)來自于跨多個服務器的Session管理。下圖對這個生產(chǎn)環(huán)境展示了一個簡單的圖形:
我將試著解釋并讓您記住各個不同應用場景。
應用程序池
這是當您在創(chuàng)建一個實際生產(chǎn)環(huán)境時最重要的一個東西。應用程序池是用在IIS里用來分隔不同的工作進程的應用程序的,應用程序池能分隔我們的應用程序,使其獲得更好的安全性,可靠性和有效性。應用程序池的應用在服務器中當一個進程出現(xiàn)問題,或者被回收時其他進程不受影響。
應用程序池的角色:
應用程序池的配置角色是一個重要的安全措施,在IIS6和IIS7里。因為當應用程序訪問資源時他指定了應用程序的身份。在IIS7里,有三種預定義的身份指定方式,這和IIS6是一樣的。
應用程序池角色 | 描述 |
LocalSystem | 內(nèi)建于服務器上管理權(quán)限的賬戶. 他能訪問本地和遠程資源. 任何服務器的文件或者資源, 我們必須把應用程序的身份設置為LocalSystem. |
LocalServices | 內(nèi)置的本地身份驗證. 他不能進行任何網(wǎng)絡訪問。 |
NetworkServices | 這是應用程序池的默認身份,NetworkServices是一個經(jīng)過驗證的本地用戶賬戶權(quán)限。 |
建立和指定應用程序池
打開IIS管理頁面,右鍵單擊應用程序池目錄->新建
給應用程序池一個ID,然后點擊OK。
現(xiàn)在,右鍵單擊一個虛擬目錄(我正在使用的StateServer站點)分配StateServerAppPool給StateServer虛擬目錄。
現(xiàn)在這個StateServer站點運行在了一個指定的獨立的應用程序池StateServerAppPool里。其他任何應用都不會影響到這個程序。這是獨立應用程序池的主要優(yōu)點。
Web Garden
默認情況下,每一個應用程序池都運行在一個獨立的工作進程里(W3Wp.exe)。我們能分配多個進程給單個應用程序池,一個應用程序池跑多個進程,這樣的情況叫做Web Garden(Web園),多個工作進程單個應用程序在很多情況下都能夠有更優(yōu)秀的輸出性能和更少的相應時間,每一個工作進程都會有他們自己的線程和內(nèi)存空間。
如上圖所示,在IIS里,將會有多個應用程序池,并且每個應用程序池至少有一個工作進程,而一個Web Garden將有多個工作進程。
在你的應用程序里,使用Web園將必然出現(xiàn)一個限制條件:如果我們使用InProc模式,我們的應用程序?qū)o法正確的工作,因為Session將工作在不同的進程里。為了避免這樣的問題,我們將使用進程外(OurProc)的Session模式,我們可以使用State Server或者SQL Server Session模式。
主要優(yōu)點:
在Web園內(nèi)的工作進程對每個進程都共享請求,如果一個進程掛了,其他的進程還能正常工作,繼續(xù)處理請求。
如何建立一個Web Garden?
右鍵單擊程序池->Performance(性能?)選項卡->選擇Web Garden(Web園)部分
默認情況下他的值為1,現(xiàn)在把他改為一個比1大的數(shù)字。
如何在Web園內(nèi)指定Session?
我已經(jīng)解釋過InProc模式是在單個工作進程中進行處理,在進程內(nèi)存儲對象,現(xiàn)在,如果我們要處理多個進程,Session處理將會變得很困難,因為每個工作進程獨享自己的內(nèi)存。那么假如第一個請求數(shù)據(jù)到了WP1并且保存了Session數(shù)據(jù),第二個請求到了WP2我將無法正確獲得Session的數(shù)據(jù),取值的話將會拋出異常。所以,請避免在Web Garden模式下使用InProc模式。
我們使用StateServer或者SQLServer模式對這種情況進行處理,之前解釋過,這兩種模式不依賴于工作進程,在之前的例子里也說過當IIS重啟你依然能訪問到Session數(shù)據(jù)。
Session模式 | 是否推薦 |
InProc | No |
StateServer | Yes |
SQLServer | Yes |
Web Farm和負載均衡
這是在生產(chǎn)環(huán)境中最常見的情形,當你需要在多臺服務器上部署你的應用時,使用這種模式的主要原因是我們要將負載均衡到多臺服務器上,一個負載均衡器被用于分發(fā)負載到多臺服務器上。
我們來看上圖,客戶端通過URL發(fā)送請求時先到負載均衡器,然后通過負載均衡器將請求分發(fā)給服務器,負載均衡器將在不同的服務器之間進行請求的分發(fā)。
現(xiàn)在我們?nèi)绾翁幚砦覀兊腟ession呢?
在WEB Farm和負載均衡情況下處理Session
在Web Farm中處理Session是一個有挑戰(zhàn)性的工作。
InProc:InProc Session模式,Session數(shù)據(jù)以對象形式被存儲在工作進程中,每個服務器將有他自己的工作進程,并將保持Session數(shù)據(jù)在內(nèi)存中。
假如一臺服務器down了,那么請求將會訪問其他服務器,而其他服務器里是不存在相應Session數(shù)據(jù)的。所以在Web Farm情形下不推薦使用InProc模式。
State Server:之前已經(jīng)解釋過如何使用和配置StateServer模式了,在WebFarm的環(huán)境下你將了解他是多么的重要,因為所有Session數(shù)據(jù)將在一個位置進行存儲。
記住,在web Farm環(huán)境里,你必須保證你有相同的
SQL Server:這是另一個選擇,這也是在Web Farm環(huán)境里的最佳選擇,我們首先需要配置數(shù)據(jù)庫,接下來的步驟之前已經(jīng)說過了。
如上圖所示,所有的web服務器Session數(shù)據(jù)都將被存儲于一個SQL Server數(shù)據(jù)庫。請記住一點,在StateServer模式和SQL Server模式下你都將把對象進行序列化存儲。當一臺Web服務器掛掉的時候,負載均衡器將把請求分發(fā)到其他服務器他將能從數(shù)據(jù)庫里取出Session數(shù)據(jù),因為所有Session數(shù)據(jù)都是存放于數(shù)據(jù)庫里的。
總之,我們能用StateServer和SQL Server模式來進行Web Farm的部署,我們需要盡量避免使用InProc模式。
Session和Cookie
客戶端使用Cookie來配合使用Session,因為客戶端需要給每個請求提供合適的Session ID,我們可以使用下列的方法:
使用Cookie
ASP.NET使用了一個特定的Cookie名叫作:ASP.NET_SessionId這是當Session集合被創(chuàng)建的時候自動提供的,這是默認設置,Session ID通過Cookie進行傳送。
Cookie Munging
當用戶向服務器發(fā)送一個請求時,服務器解碼Session ID并將他加入到每個頁面的鏈接里,當用戶點擊鏈接,ASP.NET編碼Session ID并傳送到用戶所請求的頁面,現(xiàn)在,請求的頁面可以獲取Session變量了。這一切都是自動完成的,當ASP.NET發(fā)現(xiàn)用戶瀏覽器不支持Cookie時。
如何實現(xiàn)Cookie Munging
為了這個,我們必須保證我們的Session State為Cookie-less。
移除Session
下面的方法被用來移除Session
方法 | 描述 |
Session.Remove(strSessionName) | 從Session State中移除一個項目 |
Session.RemoveAll() | 從Session集合中移除所有項目 |
Session.Clear() | 從Session集合中移除所有項目. Note: Clear和RemoveAll.RemoveAll()沒有區(qū)別Clear()是內(nèi)部的. |
Session.Abandon() | 取消當前的Session。 |
啟用和禁用Session
從性能優(yōu)化來說,我們可以啟用或禁用Session,因為每個頁面都進行讀寫Session會出現(xiàn)一些性能開銷,所以,更合適地啟用或者禁用Session,而不是使用他的默認配置:always。我們啟用和禁用Session可以采取兩種方式:
頁面級
應用級
頁面級
我們能禁用Session在頁面指令的EnableSessionState屬性中
同樣的,我們可以讓他成為只讀的,這將只允許訪問Session而禁止寫入信息到Session
應用級
通過設置web.config的屬性EnableSessionState可以讓Session在整個應用程序內(nèi)被禁用,
一般我們都是采用頁面級的限制,這樣能靈活控制Session的使用。
參考文獻:
How to Disable ASP.NET Session State
總結(jié)
希望你現(xiàn)在能更熟悉Session了,如何使用Session,以及如何在Web Farm中使用,總結(jié)如下:
1、 InProc Session Provider是最快的,因為所有數(shù)據(jù)都存在應用程序的內(nèi)存里,Session數(shù)據(jù)在IIS重啟,或者站點被回收的情況下丟失,你可以在用戶量較小的網(wǎng)站上使用這種模式,但別在Web Farm下使用。
2、 State Server模式:Session數(shù)據(jù)被存儲于aspnet_state.exe應用中,他在Web服務之外保存Session數(shù)據(jù),所以Web服務出現(xiàn)問題不會對他的Session數(shù)據(jù)造成影響,在將Session數(shù)據(jù)存儲到StateServer之前需要序列化對象,在Web Farm中我們能安全地使用這個模式。
3、 SQL Server模式:他將Session數(shù)據(jù)保存到SQL Server中,我們需要提供連接串,我們存儲時也需要對對象進行序列化,這種模式在實際Web Farm的生產(chǎn)環(huán)境中是非常有用的。
4、 我們也能使用自定義模式,當我們需要使用一個已經(jīng)存在的表來存儲Session數(shù)據(jù)時,在自定義模式中,我們也能創(chuàng)建自定義的Session ID,但是不推薦你自己來實現(xiàn)Provider,推薦使用第三方的Provider。
希望您能喜歡這篇文章,希望您能給我寶貴建議幫助大家共同提高,再次感謝您的閱讀。