日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
      軟件
      軟件
      文章
      搜索

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

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

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

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

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

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

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

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

      什么是Session

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

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

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

      Session的利弊

      接下來(lái)我們討論普通情況下使用Session的利弊,我會(huì)描述每一種Session的使用情境。

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

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

      他能讓我們簡(jiǎn)單地實(shí)現(xiàn)存儲(chǔ)任何類(lèi)型的對(duì)象。

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

      對(duì)于用戶來(lái)說(shuō),Session是安全的、透明的。

      缺點(diǎn):

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

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

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

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

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

      //Storing UserName in Session
      
      Session["UserName"] = txtUser.Text;

      接下來(lái)讓我們來(lái)看如何從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
      }

      我們也能存儲(chǔ)其他對(duì)象,下面的例子展示了如何存儲(chǔ)一個(gè)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)識(shí)符用以標(biāo)識(shí)每個(gè)Session。這是足夠安全的、不可逆的設(shè)計(jì)。當(dāng)客戶端和服務(wù)端進(jìn)行通信的時(shí)候,在他們之間需要傳輸這個(gè)Session ID,當(dāng)客戶端發(fā)送request(請(qǐng)求)數(shù)據(jù)時(shí),ASP.NET搜索Session ID,通過(guò)Session ID檢索數(shù)據(jù)。這個(gè)過(guò)程通過(guò)以下步驟進(jìn)行:

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

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

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

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

      以下為流程圖片:

      客戶端、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的信息請(qǐng)求時(shí)Session State和他相應(yīng)的Provider負(fù)責(zé)提供和存儲(chǔ)對(duì)應(yīng)的信息。下面的表展示了Session 模式以及Provider的名稱(chēng):

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

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

      Session States

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

      Session事件

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

      Session_Start

      Session_End

      你能處理應(yīng)用中的這兩個(gè)事件在global.asax這個(gè)文件里,當(dāng)一個(gè)新的Session開(kāi)啟時(shí)session_start事件被觸發(fā),當(dāng)Session被回收或是過(guò)期時(shí)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)討論過(guò)Session模式,接下來(lái)說(shuō)說(shuō)這些模式的不同:

      Off

      InProc

      StateServer

      SQLServer

      Custom

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

      InProc Session 模式:

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

      InProc概述:

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

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

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

      Session.TimeOut=30;

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

      當(dāng)Session過(guò)期時(shí)Session_End()事件被調(diào)用。InProc是一個(gè)非?斓奶幚頇C(jī)制,因?yàn)闆](méi)有序列化地讀/寫(xiě)過(guò)程,并且數(shù)據(jù)保存在相同的域內(nèi)。

      什么時(shí)候我們使用InProc模式呢?

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

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

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

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

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

      使用起來(lái)非常簡(jiǎn)單,就像ViewState一樣。

      缺點(diǎn):

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

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

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

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

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

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

      StateServer Session模式

      StateServer模式概述

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

      配置StateServer Session模式

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

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

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

      現(xiàn)在,我們來(lái)看一看web.config對(duì)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è)置超時(shí)stateNetworkTimeOut特性指定等待服務(wù)響應(yīng)的秒數(shù),即發(fā)出請(qǐng)求到取消響應(yīng)的事件時(shí)間間隔。默認(rèn)情況下是10秒。

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

      StateServer是如何工作的

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

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

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

      StateServer Session模式例子:

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

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

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

      步驟2:創(chuàng)建一個(gè)簡(jiǎn)單的UI:他將獲取一個(gè)學(xué)生的角色編號(hào)和名字,我們將保存名字和編號(hào)到StateServer Session里。我也將創(chuàng)建一個(gè)類(lèi):StudentInfo,這個(gè)類(lèi)的定義如下:

      [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)在來(lái)看后端代碼,我增加了兩個(gè)Button:一個(gè)是保存Session,另一個(gè)是獲取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,在之前介紹過(guò),請(qǐng)確保web.config在配置所指向的服務(wù)器上的State Server是處于開(kāi)啟并運(yùn)行的狀態(tài)。

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

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

      接下來(lái)的測(cè)試,我將完整的解釋如何使用StateServer

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

      清晰地指出了在存儲(chǔ)之前你必須序列化你的對(duì)象。

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

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

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

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

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

      基于上述討論:

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

      StateServer獨(dú)立于IIS運(yùn)行,所以無(wú)論IIS出什么問(wèn)題都影響不到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模式簡(jiǎn)介

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

      設(shè)置SQL Server,我們需要這些SQL腳本:

      安裝:InstallSqlState.sql

      卸載:UninstallSQLState.sql

      最簡(jiǎn)單的配置方式是利用aspnet_regsql命令。

      之前已經(jīng)解釋過(guò)了如何配置,這是最有用的狀態(tài)管理方法在web Farm模式里。

      我們?yōu)楹问褂肧QL Server模式?

      SQL Server Session模式提供了更安全、更可靠的Session管理。

      他保證了數(shù)據(jù)在一個(gè)集中式的環(huán)境中(數(shù)據(jù)庫(kù))。

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

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

      這是一個(gè)完美解決web Farm和web園的方案(這個(gè)我將在后面詳細(xì)解釋?zhuān)?/p>

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

      配置SQL Server Session模式

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

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

      第一步:進(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ù)持久化存儲(chǔ)于數(shù)據(jù)庫(kù)中
      -S服務(wù)器名
      -U用戶名
      -P密碼.

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

      配置結(jié)束。

      第三步:

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

      ASPStateTempApplications

      ASPStateTempSessions

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

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

      現(xiàn)在我們?cè)賮?lái)討論以下StateServer模式中所討論的幾個(gè)問(wèn)題:

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

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

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

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

      (注:第一種將導(dǎo)致無(wú)法序列化對(duì)象,會(huì)拋出異常,第二種無(wú)影響,第三種,在關(guān)閉數(shù)據(jù)庫(kù)服務(wù)時(shí)會(huì)有影響,而重啟數(shù)據(jù)庫(kù)服務(wù)將找回Session內(nèi)的數(shù)據(jù),因?yàn)樗浅志没瘍?chǔ)存的。)

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

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

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

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

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

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

      缺點(diǎn):

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

      對(duì)象的序列化和反序列化會(huì)成為性能瓶頸

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

      參考資料:

      Read more about SQLServer mode

      自定義Session模式

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

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

      下圖是自定義方法的處理過(guò)程:

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

      我們何時(shí)使用自定義Session模式?

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

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

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

      如何配置自定義Session模式?

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

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

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

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

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

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

      3、 我們能建立自己的Session ID邏輯來(lái)分配Session ID。

      缺點(diǎn):

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

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

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

      參考資料:

      Custom Mode

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

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

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

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

      應(yīng)用程序池

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

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

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

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

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

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

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

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

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

      Web Garden

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

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

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

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

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

      如何建立一個(gè)Web Garden?

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

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

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

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

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

      Session模式是否推薦
      InProcNo
      StateServerYes
      SQLServerYes

      Web Farm和負(fù)載均衡

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

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

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

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

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

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

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

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

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

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

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

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

      Session和Cookie

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

      使用Cookie

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

      Cookie Munging

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

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

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

      移除Session

      下面的方法被用來(lái)移除Session

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

      啟用和禁用Session

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

      頁(yè)面級(jí)

      應(yīng)用級(jí)

      頁(yè)面級(jí)

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

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

      應(yīng)用級(jí)

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

      一般我們都是采用頁(yè)面級(jí)的限制,這樣能靈活控制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ù)被存儲(chǔ)于aspnet_state.exe應(yīng)用中,他在Web服務(wù)之外保存Session數(shù)據(jù),所以Web服務(wù)出現(xiàn)問(wèn)題不會(huì)對(duì)他的Session數(shù)據(jù)造成影響,在將Session數(shù)據(jù)存儲(chǔ)到StateServer之前需要序列化對(duì)象,在Web Farm中我們能安全地使用這個(gè)模式。

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

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

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

        相關(guān)評(píng)論

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

        • 8 喜歡喜歡
        • 3 頂
        • 1 難過(guò)難過(guò)
        • 5 囧
        • 3 圍觀圍觀
        • 2 無(wú)聊無(wú)聊

        熱門(mén)評(píng)論

        最新評(píng)論

        第 2 樓 本機(jī)地址中國(guó) 網(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ā)表評(píng)論 查看所有評(píng)論(2)

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