西西軟件園多重安全檢測下載網(wǎng)站、值得信賴的軟件下載站!
軟件
軟件
文章
搜索

首頁編程開發(fā)ASP.NET → ASP.NET中的Session怎么正確使用

ASP.NET中的Session怎么正確使用

相關(guān)軟件相關(guān)文章發(fā)表評論 來源:ULiiAn·竹 譯時間:2013/12/8 9:59:29字體大。A-A+

作者:Abhijit Jana點(diǎn)擊:2779次評論:2次標(biāo)簽: Session

  • 類型:AVG冒險(xiǎn)游戲大。684M語言:中文 評分:10.0
  • 標(biāo)簽:
立即下載

Session對象用于存儲從一個用戶開始訪問某個特定的aspx的頁面起,到用戶離開為止,特定的用戶會話所需要的信息。用戶在應(yīng)用程序的頁面切換時,Session對象的變量不會被清除。
對于一個Web應(yīng)用程序而言,所有用戶訪問到的Application對象的內(nèi)容是完全一樣的;而不同用戶會話訪問到的Session對象的內(nèi)容則各不相同。  Session可以保存變量,該變量只能供一個用戶使用,也就是說,每一個網(wǎng)頁瀏覽者都有自己的Session對象變量,即Session對象具有唯一性。 

最近這兩天被一個Web Farm環(huán)境下的Session處理問題虐得很痛苦,這是一個ASP.NETSession基礎(chǔ)知識的一個合集,有的地方感覺是有重復(fù),比較啰嗦,我基本上按照原文將他翻譯出來了,小弟程序水平不高,英語水平更差(09年高考英語65分,滿分150),自我感覺Session基礎(chǔ)內(nèi)容是講清楚了,我粗淺的理解下,沒有發(fā)現(xiàn)有什么錯誤了,文章較淺,請各位發(fā)現(xiàn)有什么不對的地方告訴我,我一定盡快處理,這篇文章很適合初學(xué)者看,作者說的很清楚,能把ASP.NET下Session的玩法看得較為清晰。另外我會在我另一篇博文中將我所遇到的問題以及解決辦法和大家共享。原文地址:http://www.codeproject.com/Articles/32545/Exploring-Session-in-ASP-Net

這篇文章將使你非常好地理解Session,在這篇文章中,我會包含Session的基礎(chǔ)知識,用不同的方式儲存Session對象,包含Web園(Web Farm)和Web農(nóng)場(Web Garden)以及負(fù)載均衡等等情境。我也將詳細(xì)闡明Session在實(shí)際生產(chǎn)環(huán)境中的應(yīng)用。希望您能喜歡這篇文章,歡迎您反饋您的看法和建議。

什么是Session

Web是無狀態(tài)的,他提供了一種新的方式:每次都通過用戶對服務(wù)器提交請求而渲染新的網(wǎng)頁。眾所周知,HTTP是一種無狀態(tài)協(xié)議,他不能通過頁面和客戶端保持連接。如果用戶需要增加一些信息和跳轉(zhuǎn)到了另外的頁面,原有的數(shù)據(jù)將會丟失,用戶將無法恢復(fù)這些信息。我們需要這玩意兒干嘛呢?我們需要保存信息!Session提供了一個在服務(wù)器端保存信息的方案。他能支持任何類型對象和用戶對象信息作為對象保存起來。Session為每一個客戶端都獨(dú)立地保存,這意味著Session數(shù)據(jù)存儲著每個客戶端的基礎(chǔ)信息。請看下圖:

每一個客戶端都有一份獨(dú)立的Session

用Session進(jìn)行狀態(tài)管理是ASP.NET最好的特性之一,因?yàn)樗前踩,對于客戶端是透明的,并且他能存儲任何類型的對象。而在這些優(yōu)點(diǎn)之外,有時Session會導(dǎo)致一些對性能要求較高的網(wǎng)站的性能問題。因?yàn)樗姆⻊?wù)器的內(nèi)存存儲用戶訪問網(wǎng)站所需的數(shù)據(jù),現(xiàn)在讓我們來看一看Session對于您Web 應(yīng)用的利弊。

Session的利弊

接下來我們討論普通情況下使用Session的利弊,我會描述每一種Session的使用情境。

優(yōu)點(diǎn):

他能在整個應(yīng)用中幫助維護(hù)用戶狀態(tài)和數(shù)據(jù)。

他能讓我們簡單地實(shí)現(xiàn)存儲任何類型的對象。

獨(dú)立地保存客戶端數(shù)據(jù)。

對于用戶來說,Session是安全的、透明的。

缺點(diǎn):

因?yàn)镾ession使用的是服務(wù)器的內(nèi)存,所以在用戶量大的時候會成為性能瓶頸。

在序列化和反序列化的過程中他也會成為性能瓶頸,因?yàn)樵赟tateServer(狀態(tài)服務(wù))模式和SQL Server模式下我們需要對我們存儲的數(shù)據(jù)進(jìn)行序列化和反序列化我們所存儲的數(shù)據(jù)。

除此之外,Session的各種模式都有其利弊。接下來我們將討論各種Session模式。

對Session進(jìn)行讀/寫

讀/寫Session是非常簡單的,就像使用ViewState一樣,我們能使用System.Web.SessionState.HttpSessionState這個類來與Session進(jìn)行交互,這個類在ASP.NET頁面內(nèi)內(nèi)建(提供)了Session。下面的代碼就是使用Session進(jìn)行存儲的例子:

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

參考文獻(xiàn):

MSDN (read the session variable section)

Session ID

ASP.NET使用了120bit的標(biāo)識符用以標(biāo)識每個Session。這是足夠安全的、不可逆的設(shè)計(jì)。當(dāng)客戶端和服務(wù)端進(jìn)行通信的時候,在他們之間需要傳輸這個Session ID,當(dāng)客戶端發(fā)送request(請求)數(shù)據(jù)時,ASP.NET搜索Session ID,通過Session ID檢索數(shù)據(jù)。這個過程通過以下步驟進(jìn)行:

客戶端點(diǎn)擊網(wǎng)站->客戶端信息被Session儲存

服務(wù)端為客戶端創(chuàng)建一個唯一的Session ID,并在服務(wù)端存儲這個ID

客戶端通過發(fā)送帶有SessionID的請求以獲取在服務(wù)端保存的信息

服務(wù)器端通過Session Provider從狀態(tài)服務(wù)(State Server)中獲取序列化后的數(shù)據(jù)并且進(jìn)行類型強(qiáng)制轉(zhuǎn)換成對象

以下為流程圖片:

客戶端、Web服務(wù)器、Session Provider的通信

參考文獻(xiàn):

SessionID in MSDN

Session模式和Session Provider

在ASP.NET中,有以下幾種Session模式可以使用

InProc

StateServer

SQLServer

Custom

每一種Session State都有一種Session Provider。以下的圖形將展示他們的關(guān)系:

Session state體系圖

我們能在這些基礎(chǔ)的Session State Provider中進(jìn)行選擇。當(dāng)ASP.NET接收到帶有Session ID的信息請求時Session State和他相應(yīng)的Provider負(fù)責(zé)提供和存儲對應(yīng)的信息。下面的表展示了Session 模式以及Provider的名稱:

Session State模式State Provider
InProcIn-memory object(內(nèi)置對象)
StateServerAspnet_state.exe
SQLServerSQL Server Database
CustomCustom provider

除此之外,還有另一個模式:“OFF”,如果我們選擇這個選項(xiàng),Session將不能為這個應(yīng)用提供服務(wù)。但是我們的目標(biāo)是使用Session,所以我們將討論上面四種的Session模式。

Session States

Session State模式基本上可以認(rèn)為把所有的Session配置、維護(hù)都交給了Web應(yīng)用。Session State他本身就是一個大東西,他基本上意味著你所有關(guān)于Session 的配置無論實(shí)在web.config或者頁面后端代碼。在web.config里元素被用作Session的配置。在元素中可以配置的有Mode(模式),Timeout(超時),StateConnectionString(State連接字符串),CustomProvider(自定義的Provider)等等。我們已經(jīng)討論過了每個部分的連接字符串在我們討論Session mode之前,接下來我們簡述以下Session的一些事件:

Session事件

在ASP.NET中有兩個可以使用的Session事件:

Session_Start

Session_End

你能處理應(yīng)用中的這兩個事件在global.asax這個文件里,當(dāng)一個新的Session開啟時session_start事件被觸發(fā),當(dāng)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. 
}

參考文獻(xiàn):

Application and Session Events

Session 模式

我們已經(jīng)討論過Session模式,接下來說說這些模式的不同:

Off

InProc

StateServer

SQLServer

Custom

如果我們在web.config內(nèi)設(shè)定Session Mode="off",Session將在應(yīng)用中不可用,他的設(shè)置是這樣的:

InProc Session 模式:

這是ASP.NET默認(rèn)的Session模式,他在當(dāng)前的應(yīng)用程序域中存儲Session信息。這是性能最好的Session模式。但是他最大的缺點(diǎn)在于:當(dāng)我們重啟服務(wù)的時候Session數(shù)據(jù)將會丟失。InProc模式有一些優(yōu)缺點(diǎn),接下來我們將詳細(xì)這些點(diǎn)。

InProc概述:

我們已經(jīng)說過,InProc模式Session數(shù)據(jù)將會儲存在當(dāng)前應(yīng)用程序域中,所以他是最簡單、快速、好用的。

InProc模式Session數(shù)據(jù)保存在應(yīng)用程序域內(nèi)的一個集合對象,他在一個應(yīng)用程序池中進(jìn)行工作,如果我們重啟服務(wù),我們將丟失Session數(shù)據(jù)。正常情況下客戶端發(fā)送請求,State Provider從內(nèi)存對象中讀取數(shù)據(jù)并返回給客戶端,在web.config中我們必須提供Session模式和設(shè)置過期時間:

上面的設(shè)置中,設(shè)置了Session的過期時間為30分鐘,這也可以從后臺代碼中進(jìn)行配置。

Session.TimeOut=30;

在ASP.NET中有兩個Session事件可以進(jìn)行使用:Session_Start()和Session_End()而這種模式(后端代碼控制)只支持Session_End()事件。這個事件在Session超時時被調(diào)用,一般情況下,InProc Session模式是這樣的:

當(dāng)Session過期時Session_End()事件被調(diào)用。InProc是一個非常快的處理機(jī)制,因?yàn)闆]有序列化地讀/寫過程,并且數(shù)據(jù)保存在相同的域內(nèi)。

什么時候我們使用InProc模式呢?

InProc是默認(rèn)的Session模式,他對小型應(yīng)用程序和用戶量比較小的程序非常合適,我們應(yīng)盡量避免在Web園(Web Garden)和Web農(nóng)場(Web Farm)情境下使用他(以后我會講到這個情境)

優(yōu)缺點(diǎn):

優(yōu)點(diǎn):

他把Session數(shù)據(jù)存儲在當(dāng)前應(yīng)用程序域內(nèi),所以訪問數(shù)據(jù)會非常的快速、簡單、高效。

在InProc模式中不需要對對象進(jìn)行序列化存儲。

使用起來非常簡單,就像ViewState一樣。

缺點(diǎn):

雖然InProc是最快的,最通用的,也是默認(rèn)的機(jī)制,但是他有許多限制:

如果工作的應(yīng)用進(jìn)程被回收,Session數(shù)據(jù)將全部丟失。

雖然他是最快的,但是當(dāng)Session數(shù)據(jù)太大和用戶過多時,他會由于內(nèi)存的大量使用而影響整個程序的性能。

我們不能在Web園環(huán)境中使用這種模式。

這種模式不適合用于Web農(nóng)場(Web Farm)環(huán)境中。

現(xiàn)在,我們來看看其他可用的方法來規(guī)避這些缺點(diǎn),首先是StateServer模式:

StateServer Session模式

StateServer模式概述

這也叫做Out-Proc Session模式。StateServer使用了一個獨(dú)立的Windows服務(wù)來提供Session服務(wù),他獨(dú)立于IIS,也能獨(dú)使用一臺服務(wù)器。StateServer的服務(wù)來自于aspnet_state.exe提供。這個服務(wù)也能和您的應(yīng)用服務(wù)共同運(yùn)行在同一臺服務(wù)器上,注意他是獨(dú)立于Web應(yīng)用程序域的一個服務(wù)。這意味著你重啟你的Web服務(wù)后Session數(shù)據(jù)依然存在。這個方案的缺點(diǎn)在于有一個性能瓶頸:數(shù)據(jù)讀寫需要進(jìn)行序列化和反序列化,因?yàn)椴皇峭粋應(yīng)用程序域,所以他也增加了數(shù)據(jù)讀寫的性能消耗,因?yàn)樗麄兪莾蓚不同的進(jìn)程。

配置StateServer Session模式

在StateServer模式里,Session數(shù)據(jù)存儲在獨(dú)立于IIS的一個服務(wù)里。這個進(jìn)程作為一個Windows服務(wù)運(yùn)行,你能在Windows服務(wù)管理器(MMC)或者命令行中進(jìn)行啟動。

默認(rèn)情況下,ASP.NET StateServer(中文名:ASP.NET狀態(tài)服務(wù))默認(rèn)情況下啟動方式是“手動”我們必須將他設(shè)置為自動。

如果從命令行啟動的化只需要輸入:"net start aspnet_state";默認(rèn)情況下,這個服務(wù)監(jiān)聽TCP端口42424,但是我們可以在注冊表里改變這個設(shè)置,如圖:

現(xiàn)在,我們來看一看web.config對StateServer的設(shè)置,在StateServer的設(shè)置里我們需要指定StateServer連接字符串stateConnectionString:指向運(yùn)行StateServer的系統(tǒng)。默認(rèn)設(shè)置下,StateConnectionString使用IP127.0.0.1(localhost)端口使用42424。

當(dāng)我們使用StateServer,我們還能設(shè)置超時stateNetworkTimeOut特性指定等待服務(wù)響應(yīng)的秒數(shù),即發(fā)出請求到取消響應(yīng)的事件時間間隔。默認(rèn)情況下是10秒。

當(dāng)使用StateServer進(jìn)行存儲時對象將被序列化進(jìn)行儲存,而讀取對象時,將對數(shù)據(jù)進(jìn)行反序列化,我們來看下面的例子:

StateServer是如何工作的

我們使用StateServer來避免當(dāng)重啟Web服務(wù)時無謂的Session數(shù)據(jù)丟失。StateServer是在aspnet_state.exe進(jìn)程作為一個服務(wù)來進(jìn)行維護(hù)的,這個進(jìn)程維護(hù)著所有的Session數(shù)據(jù),但是在存儲到StateServer之前我們需要對數(shù)據(jù)進(jìn)行序列化。

如上圖所示,客戶端發(fā)送請求到Web服務(wù)器,Web服務(wù)器將Session數(shù)據(jù)存儲在StateServer里,StateServer也許在當(dāng)前的系統(tǒng)里,也可能在另一個系統(tǒng)里,但他一定是獨(dú)立于IIS的,為了實(shí)現(xiàn)他,我們必須在web.config里進(jìn)行配置stateConnectionString。例如我們設(shè)置指向127.0.0.1:42424,這將把數(shù)據(jù)存儲在本地的系統(tǒng)內(nèi),為了實(shí)現(xiàn)改變StateServer指向的目的,我們改變了IP,并且確定aspnet_state.exe正常運(yùn)行于這個系統(tǒng)上,接下來當(dāng)你需要讀寫Session時(也就是通過修改IP來導(dǎo)致一個錯誤的指向),你就會引發(fā)下圖這樣的異常:

當(dāng)我們存儲一個對象到Session,對象將被序列化。系統(tǒng)利用State Provider將數(shù)據(jù)存儲進(jìn)StateServer。當(dāng)讀取數(shù)據(jù)時,State Provider將返回?cái)?shù)據(jù),完整的流程圖如下圖:

StateServer Session模式例子:

這是一個簡單的使用StateServer Session模式的例子,我直接在IIS里創(chuàng)建這個例子,能輕松地明白他的用法:

步驟1:打開Visual Studio>文件>新建>網(wǎng)站。選擇HTTP作為web應(yīng)用的位置。

現(xiàn)在你打開IIS,你將會看到創(chuàng)建了一個虛擬目錄,名字是你的應(yīng)用名,在我的例子中是StateServer。

步驟2:創(chuàng)建一個簡單的UI:他將獲取一個學(xué)生的角色編號和名字,我們將保存名字和編號到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在配置所指向的服務(wù)器上的State Server是處于開啟并運(yùn)行的狀態(tài)。

步驟4:運(yùn)行應(yīng)用。

輸入數(shù)據(jù),點(diǎn)擊Submit。

接下來的測試,我將完整的解釋如何使用StateServer

首先:移除StudentInfo類[Serializable]特性,然后運(yùn)行應(yīng)用。當(dāng)你點(diǎn)解Submit按鈕,你將看到如下的錯誤:

清晰地指出了在存儲之前你必須序列化你的對象。

第二:運(yùn)行程序,在點(diǎn)擊了Submit按鈕保存數(shù)據(jù)后,重啟IIS

如果在InProc中,我保證你的Session數(shù)據(jù)將會丟失,但是在StateServer中,點(diǎn)擊Restore Session按鈕,你將獲取你的原始數(shù)據(jù),因?yàn)镾tateServer數(shù)據(jù)不依賴于IIS,它獨(dú)立地保存數(shù)據(jù)。

第三:在Windows 服務(wù)管理程序(MMC)中停止StateServer服務(wù),你再點(diǎn)擊Submit按鈕,你將看到如下錯誤:

因?yàn)槟愕腟tateServer進(jìn)程沒有運(yùn)行,所以當(dāng)你在使用StateServer的時候,請牢記這三點(diǎn)。

優(yōu)點(diǎn)和缺點(diǎn)

基于上述討論:

優(yōu)點(diǎn):

StateServer獨(dú)立于IIS運(yùn)行,所以無論IIS出什么問題都影響不到StateServer的數(shù)據(jù)。

他能在Web Farm和Web Garden環(huán)境中使用。

缺點(diǎn):

要進(jìn)行序列化和反序列化,拖慢速度。

StateServer需要保證正常運(yùn)行。

我在這里停止StateServer的講述,你將在負(fù)載均衡中看到他更多更有趣的點(diǎn),Web Farm,Web Garden情境下。

參考文獻(xiàn):

State Server Session Mode

ASP.NET Session State

SQL Server Session模式

SQL Server模式簡介

ASP.NET這個Session模式提供給我們了更強(qiáng)的安全性和可靠性,在這個模式下,Session數(shù)據(jù)被序列化并存儲到一個SQL Server的數(shù)據(jù)庫中,這個模式缺點(diǎn)在于Session需要序列化和反序列化的讀寫方式成為了主要的性能瓶頸,他是Web Farm的最佳選擇。

設(shè)置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ù)庫)。

當(dāng)我們需要更安全地實(shí)現(xiàn)Session時就應(yīng)該使用SQL Server模式。

假如服務(wù)器經(jīng)常需要重啟,這是一個完美的解決方案。

這是一個完美解決web Farm和web園的方案(這個我將在后面詳細(xì)解釋)。

當(dāng)我們需要在兩個應(yīng)用間共享Session時我們需要使用SQL Server模式。

配置SQL Server Session模式

在SQL Server模式中,我們的數(shù)據(jù)保存在SQL Server中,所以我們首先要在web.config里提供數(shù)據(jù)庫連接字符串,sqlConnectionString是被用來做這事的。

在連接字符串配置完成后,我們將要配置SQL Server,我將在這里演示如何用aspnet_regsql命令進(jìn)行數(shù)據(jù)庫配置。

第一步:進(jìn)入命令行,進(jìn)入到Framework version目錄E.g. :c:\windows\microsoft.net\framework\

第二步,帶參運(yùn)行aspnet_regsql命令。

下面是參數(shù)的使用:

ParametersDescription
-ssadd增加 SQLServer 模式 session state.
-sstype pP 持久化.將這些數(shù)據(jù)持久化存儲于數(shù)據(jù)庫中
-S服務(wù)器名
-U用戶名
-P密碼.

運(yùn)行結(jié)束后,你見看到如下的信息:

配置結(jié)束。

第三步:

打開SQL Server,查看數(shù)據(jù)庫ASPState庫,將有兩張表:

ASPStateTempApplications

ASPStateTempSessions

更改設(shè)置中的連接字符串,建立一個像StateServer例子中那樣的應(yīng)用

點(diǎn)擊Submit時保存Roll Number和用戶名,打開數(shù)據(jù)庫,進(jìn)入ASPStateTempSessions表,這是你保存的Session數(shù)據(jù):

現(xiàn)在我們再來討論以下StateServer模式中所討論的幾個問題:

1、從StydentInfo類中移除Serialize特性(keyword)

2、重啟IIS再讀取Session數(shù)據(jù)

3、停止SQL Server服務(wù)

我想這些問題我已經(jīng)在StateServer解釋得很清楚了。

(注:第一種將導(dǎo)致無法序列化對象,會拋出異常,第二種無影響,第三種,在關(guān)閉數(shù)據(jù)庫服務(wù)時會有影響,而重啟數(shù)據(jù)庫服務(wù)將找回Session內(nèi)的數(shù)據(jù),因?yàn)樗浅志没瘍Υ娴摹#?/p>

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

Session數(shù)據(jù)不受IIS重啟的影響

最可靠和最安全的Session管理模式

他在本地中心化保存Session數(shù)據(jù),能使其他應(yīng)用方便地進(jìn)行訪問

在Web Farm 和Web Garden情境下非常實(shí)用

缺點(diǎn):

和默認(rèn)模式比較起來,會顯得很慢

對象的序列化和反序列化會成為性能瓶頸

因?yàn)樾枰诓煌姆⻊?wù)器上訪問SQL Server,我們必須保證SQL Server的穩(wěn)定運(yùn)行。

參考資料:

Read more about SQLServer mode

自定義Session模式

通常情況下,我們使用InProc模式、StateServer模式、SQL Server模式就夠了,可是我們還是需要了解一些用戶自定義Session模式的相關(guān)知識。這是一種相當(dāng)有趣的Session模式,因?yàn)橛脩舻腟ession全部交由了我們進(jìn)行控制,甚至Session ID,你都能通過自己寫算法來生成Session ID。

你能夠容易地從基類SessionStateStoreProviderBase開發(fā)出自定義的Provider,你也能通過實(shí)現(xiàn)ISessionIDManager接口來產(chǎn)生SessionID。

下圖是自定義方法的處理過程:

在Initialize方法中,我們能設(shè)置一個自定義Provider。他將提供給Provider初始化連接。SetItemExpireCallback被用作提供SessionTimeOut(Session過期),當(dāng)Session過期時我們能注冊一個方法進(jìn)行調(diào)用。InitializeRequest在請求發(fā)起的時候被調(diào)用,CreateNewStoreData在創(chuàng)建一個SessionStateStoreData(Session數(shù)據(jù)存儲類)實(shí)例時候被調(diào)用。

我們何時使用自定義Session模式?

1、 當(dāng)我們想將Session數(shù)據(jù)存儲在SQL Server之外的數(shù)據(jù)庫內(nèi)時。

2、 當(dāng)我們必須使用一個已存在的(特定的)表來存儲Session數(shù)據(jù)的時候。

3、 當(dāng)我們需要使用自定義的SessionID的時候

如何配置自定義Session模式?

我們需要在web.config里進(jìn)行這樣的配置:

如果你想了解更多的關(guān)于自定義模式的信息,請查閱參考資料。

優(yōu)缺點(diǎn):

優(yōu)點(diǎn):

1、 我們能使用一個已存在的表(指定的表)來存儲Session數(shù)據(jù)。當(dāng)我們使用一個之前使用的數(shù)據(jù)庫時,這樣做是很有用的。

2、 他獨(dú)立于IIS運(yùn)行,所以重啟服務(wù)器對他也沒有影響。

3、 我們能建立自己的Session ID邏輯來分配Session ID。

缺點(diǎn):

1、 處理數(shù)據(jù)很慢。

2、 創(chuàng)建一個自定義的Session狀態(tài)Provider是一個基礎(chǔ)性(low-level)任務(wù),他需要小心處理各種情況以及保證數(shù)據(jù)安全。

我推薦您使用第三方提供的Provider而不是自己寫一套Provider。

參考資料:

Custom Mode

生產(chǎn)部署的概述:

在實(shí)際的生產(chǎn)工作環(huán)境中部署我們的應(yīng)用對于一個Web開發(fā)者來說是一個非常重大的挑戰(zhàn)。因?yàn)樵诖蟮纳a(chǎn)環(huán)境中,有大量的用戶數(shù)據(jù)需要處理,數(shù)據(jù)量大到一臺服務(wù)器難以負(fù)載這么巨大的數(shù)據(jù)處理量。這個概念來自于Web Farm,Web Garden,負(fù)載均衡的使用。

在幾個月前,我部署了一個實(shí)際環(huán)境:這個環(huán)境要處理百萬級的用戶訪問以及超過10個域控制器,通過負(fù)載均衡搭載了超過10臺服務(wù)器和服務(wù)數(shù)據(jù)庫。例如交易服務(wù)器、LCS服務(wù)器。最大的挑戰(zhàn)來自于跨多個服務(wù)器的Session管理。下圖對這個生產(chǎn)環(huán)境展示了一個簡單的圖形:

我將試著解釋并讓您記住各個不同應(yīng)用場景。

應(yīng)用程序池

這是當(dāng)您在創(chuàng)建一個實(shí)際生產(chǎn)環(huán)境時最重要的一個東西。應(yīng)用程序池是用在IIS里用來分隔不同的工作進(jìn)程的應(yīng)用程序的,應(yīng)用程序池能分隔我們的應(yīng)用程序,使其獲得更好的安全性,可靠性和有效性。應(yīng)用程序池的應(yīng)用在服務(wù)器中當(dāng)一個進(jìn)程出現(xiàn)問題,或者被回收時其他進(jìn)程不受影響。

應(yīng)用程序池的角色:

應(yīng)用程序池的配置角色是一個重要的安全措施,在IIS6和IIS7里。因?yàn)楫?dāng)應(yīng)用程序訪問資源時他指定了應(yīng)用程序的身份。在IIS7里,有三種預(yù)定義的身份指定方式,這和IIS6是一樣的。

應(yīng)用程序池角色描述
LocalSystem內(nèi)建于服務(wù)器上管理權(quán)限的賬戶. 他能訪問本地和遠(yuǎn)程資源. 任何服務(wù)器的文件或者資源, 我們必須把應(yīng)用程序的身份設(shè)置為LocalSystem.
LocalServices內(nèi)置的本地身份驗(yàn)證. 他不能進(jìn)行任何網(wǎng)絡(luò)訪問。
NetworkServices這是應(yīng)用程序池的默認(rèn)身份,NetworkServices是一個經(jīng)過驗(yàn)證的本地用戶賬戶權(quán)限。

建立和指定應(yīng)用程序池

打開IIS管理頁面,右鍵單擊應(yīng)用程序池目錄->新建

給應(yīng)用程序池一個ID,然后點(diǎn)擊OK。

現(xiàn)在,右鍵單擊一個虛擬目錄(我正在使用的StateServer站點(diǎn))分配StateServerAppPool給StateServer虛擬目錄。

現(xiàn)在這個StateServer站點(diǎn)運(yùn)行在了一個指定的獨(dú)立的應(yīng)用程序池StateServerAppPool里。其他任何應(yīng)用都不會影響到這個程序。這是獨(dú)立應(yīng)用程序池的主要優(yōu)點(diǎn)。

Web Garden

默認(rèn)情況下,每一個應(yīng)用程序池都運(yùn)行在一個獨(dú)立的工作進(jìn)程里(W3Wp.exe)。我們能分配多個進(jìn)程給單個應(yīng)用程序池,一個應(yīng)用程序池跑多個進(jìn)程,這樣的情況叫做Web Garden(Web園),多個工作進(jìn)程單個應(yīng)用程序在很多情況下都能夠有更優(yōu)秀的輸出性能和更少的相應(yīng)時間,每一個工作進(jìn)程都會有他們自己的線程和內(nèi)存空間。

如上圖所示,在IIS里,將會有多個應(yīng)用程序池,并且每個應(yīng)用程序池至少有一個工作進(jìn)程,而一個Web Garden將有多個工作進(jìn)程。

在你的應(yīng)用程序里,使用Web園將必然出現(xiàn)一個限制條件:如果我們使用InProc模式,我們的應(yīng)用程序?qū)o法正確的工作,因?yàn)镾ession將工作在不同的進(jìn)程里。為了避免這樣的問題,我們將使用進(jìn)程外(OurProc)的Session模式,我們可以使用State Server或者SQL Server Session模式。

主要優(yōu)點(diǎn):

在Web園內(nèi)的工作進(jìn)程對每個進(jìn)程都共享請求,如果一個進(jìn)程掛了,其他的進(jìn)程還能正常工作,繼續(xù)處理請求。

如何建立一個Web Garden?

右鍵單擊程序池->Performance(性能?)選項(xiàng)卡->選擇Web Garden(Web園)部分

默認(rèn)情況下他的值為1,現(xiàn)在把他改為一個比1大的數(shù)字。

如何在Web園內(nèi)指定Session?

我已經(jīng)解釋過InProc模式是在單個工作進(jìn)程中進(jìn)行處理,在進(jìn)程內(nèi)存儲對象,現(xiàn)在,如果我們要處理多個進(jìn)程,Session處理將會變得很困難,因?yàn)槊總工作進(jìn)程獨(dú)享自己的內(nèi)存。那么假如第一個請求數(shù)據(jù)到了WP1并且保存了Session數(shù)據(jù),第二個請求到了WP2我將無法正確獲得Session的數(shù)據(jù),取值的話將會拋出異常。所以,請避免在Web Garden模式下使用InProc模式。

我們使用StateServer或者SQLServer模式對這種情況進(jìn)行處理,之前解釋過,這兩種模式不依賴于工作進(jìn)程,在之前的例子里也說過當(dāng)IIS重啟你依然能訪問到Session數(shù)據(jù)。

Session模式是否推薦
InProcNo
StateServerYes
SQLServerYes

Web Farm和負(fù)載均衡

這是在生產(chǎn)環(huán)境中最常見的情形,當(dāng)你需要在多臺服務(wù)器上部署你的應(yīng)用時,使用這種模式的主要原因是我們要將負(fù)載均衡到多臺服務(wù)器上,一個負(fù)載均衡器被用于分發(fā)負(fù)載到多臺服務(wù)器上。

我們來看上圖,客戶端通過URL發(fā)送請求時先到負(fù)載均衡器,然后通過負(fù)載均衡器將請求分發(fā)給服務(wù)器,負(fù)載均衡器將在不同的服務(wù)器之間進(jìn)行請求的分發(fā)。

現(xiàn)在我們?nèi)绾翁幚砦覀兊腟ession呢?

在WEB Farm和負(fù)載均衡情況下處理Session

在Web Farm中處理Session是一個有挑戰(zhàn)性的工作。

InProc:InProc Session模式,Session數(shù)據(jù)以對象形式被存儲在工作進(jìn)程中,每個服務(wù)器將有他自己的工作進(jìn)程,并將保持Session數(shù)據(jù)在內(nèi)存中。

假如一臺服務(wù)器down了,那么請求將會訪問其他服務(wù)器,而其他服務(wù)器里是不存在相應(yīng)Session數(shù)據(jù)的。所以在Web Farm情形下不推薦使用InProc模式。

State Server:之前已經(jīng)解釋過如何使用和配置StateServer模式了,在WebFarm的環(huán)境下你將了解他是多么的重要,因?yàn)樗蠸ession數(shù)據(jù)將在一個位置進(jìn)行存儲。

記住,在web Farm環(huán)境里,你必須保證你有相同的節(jié)在你所有的web服務(wù)器上,其他配置和之前描述的一致,所有的web.config文件都要有相同的配置屬性(stateConnectionString)在Session State里。

SQL Server:這是另一個選擇,這也是在Web Farm環(huán)境里的最佳選擇,我們首先需要配置數(shù)據(jù)庫,接下來的步驟之前已經(jīng)說過了。

如上圖所示,所有的web服務(wù)器Session數(shù)據(jù)都將被存儲于一個SQL Server數(shù)據(jù)庫。請記住一點(diǎn),在StateServer模式和SQL Server模式下你都將把對象進(jìn)行序列化存儲。當(dāng)一臺Web服務(wù)器掛掉的時候,負(fù)載均衡器將把請求分發(fā)到其他服務(wù)器他將能從數(shù)據(jù)庫里取出Session數(shù)據(jù),因?yàn)樗蠸ession數(shù)據(jù)都是存放于數(shù)據(jù)庫里的。

總之,我們能用StateServer和SQL Server模式來進(jìn)行Web Farm的部署,我們需要盡量避免使用InProc模式。

Session和Cookie

客戶端使用Cookie來配合使用Session,因?yàn)榭蛻舳诵枰o每個請求提供合適的Session ID,我們可以使用下列的方法:

使用Cookie

ASP.NET使用了一個特定的Cookie名叫作:ASP.NET_SessionId這是當(dāng)Session集合被創(chuàng)建的時候自動提供的,這是默認(rèn)設(shè)置,Session ID通過Cookie進(jìn)行傳送。

Cookie Munging

當(dāng)用戶向服務(wù)器發(fā)送一個請求時,服務(wù)器解碼Session ID并將他加入到每個頁面的鏈接里,當(dāng)用戶點(diǎn)擊鏈接,ASP.NET編碼Session ID并傳送到用戶所請求的頁面,現(xiàn)在,請求的頁面可以獲取Session變量了。這一切都是自動完成的,當(dāng)ASP.NET發(fā)現(xiàn)用戶瀏覽器不支持Cookie時。

如何實(shí)現(xiàn)Cookie Munging

為了這個,我們必須保證我們的Session State為Cookie-less。

移除Session

下面的方法被用來移除Session

方法描述
Session.Remove(strSessionName)從Session State中移除一個項(xiàng)目
Session.RemoveAll()從Session集合中移除所有項(xiàng)目
Session.Clear()從Session集合中移除所有項(xiàng)目. Note: Clear和RemoveAll.RemoveAll()沒有區(qū)別Clear()是內(nèi)部的.
Session.Abandon()取消當(dāng)前的Session。

啟用和禁用Session

從性能優(yōu)化來說,我們可以啟用或禁用Session,因?yàn)槊總頁面都進(jìn)行讀寫Session會出現(xiàn)一些性能開銷,所以,更合適地啟用或者禁用Session,而不是使用他的默認(rèn)配置:always。我們啟用和禁用Session可以采取兩種方式:

頁面級

應(yīng)用級

頁面級

我們能禁用Session在頁面指令的EnableSessionState屬性中

同樣的,我們可以讓他成為只讀的,這將只允許訪問Session而禁止寫入信息到Session

應(yīng)用級

通過設(shè)置web.config的屬性EnableSessionState可以讓Session在整個應(yīng)用程序內(nèi)被禁用,

一般我們都是采用頁面級的限制,這樣能靈活控制Session的使用。

參考文獻(xiàn):

How to Disable ASP.NET Session State

總結(jié)

希望你現(xiàn)在能更熟悉Session了,如何使用Session,以及如何在Web Farm中使用,總結(jié)如下:

1、 InProc Session Provider是最快的,因?yàn)樗袛?shù)據(jù)都存在應(yīng)用程序的內(nèi)存里,Session數(shù)據(jù)在IIS重啟,或者站點(diǎn)被回收的情況下丟失,你可以在用戶量較小的網(wǎng)站上使用這種模式,但別在Web Farm下使用。

2、 State Server模式:Session數(shù)據(jù)被存儲于aspnet_state.exe應(yīng)用中,他在Web服務(wù)之外保存Session數(shù)據(jù),所以Web服務(wù)出現(xiàn)問題不會對他的Session數(shù)據(jù)造成影響,在將Session數(shù)據(jù)存儲到StateServer之前需要序列化對象,在Web Farm中我們能安全地使用這個模式。

3、 SQL Server模式:他將Session數(shù)據(jù)保存到SQL Server中,我們需要提供連接串,我們存儲時也需要對對象進(jìn)行序列化,這種模式在實(shí)際Web Farm的生產(chǎn)環(huán)境中是非常有用的。

4、 我們也能使用自定義模式,當(dāng)我們需要使用一個已經(jīng)存在的表來存儲Session數(shù)據(jù)時,在自定義模式中,我們也能創(chuàng)建自定義的Session ID,但是不推薦你自己來實(shí)現(xiàn)Provider,推薦使用第三方的Provider。

希望您能喜歡這篇文章,希望您能給我寶貴建議幫助大家共同提高,再次感謝您的閱讀。

    相關(guān)評論

    閱讀本文后您有什么感想? 已有人給出評價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過難過
    • 5 囧
    • 3 圍觀圍觀
    • 2 無聊無聊

    熱門評論

    最新評論

    第 2 樓 本機(jī)地址中國 網(wǎng)友 客人 發(fā)表于: 2016/5/15 23:58:35
    很好

    支持( 0 ) 蓋樓(回復(fù))

    第 1 樓 本機(jī)地址CZ88.NET 網(wǎng)友 客人 發(fā)表于: 2015/7/16 11:05:22
    很好,很詳細(xì)。

    支持( 0 ) 蓋樓(回復(fù))

    發(fā)表評論 查看所有評論(2)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)