溫故而知新:Asp.Net中如何正確使用Session

來源:互聯網
上載者:User

Asp.Net中的Session要比Asp中的Session靈活和強大很多,同時也複雜很多;看到有一些Asp.Net開發人員報怨說Session不穩定,莫名其妙的丟失,其實這正是Asp.Net改進的地方之一.

 

我們知道Session與Cookie最大的區別在於:Cookie資訊全部存放於用戶端,Session則只是將一個ID存放在用戶端做為與服務端驗證的標記,而真正的資料都是放在服務端的記憶體之中的。

 

在傳統web程式設計語言(比如asp)中,session的到期完全是按照TimeOut來老老實實處理的,逾時值預設是20分鐘,但問題是:通常有很多使用者只看一眼網頁,然後就關瀏覽器走人了,這種情況下,服務端記憶體裡還長久儲存著Session的資料,如果這種使用者很多,對伺服器資源無疑是一種浪費。

 

而在Asp.Net中,Session的儲存策略有好幾種:

預設情況下,系統採用的是InProc模式,即進程內模式。

這種情況下,Session是儲存在Asp.Net背景工作處理序映射的記憶體中的,問題是Asp.Net背景工作處理序為了維護良好的平均效能,會被系統經常回收。我們在IIS裡可以配置自動回收(比如按時間周期回收,或者當記憶體使用量達到多少值時自動回收),如即為IIS7中配置應用程式集區回收參數的介面

 

當Asp.Net背景工作處理序被回收時,其映射的記憶體全部被清空並初始化,以便其它程式可以使用,所以Session也跟著一併消失了,就這是為什麼Sesssion會無故消失的主要原因。

 

當然預設的InProc模式也是效能最高的一種模式,如果您不能忍受這種“不穩定”,可以在web.config中把mode設定為StateServer模式

<sessionState  mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424"></sessionState>

這種情況下Session會被儲存在Asp.Net進程之外的aspnet_state.exe進程中,這個進程不受asp.net進程回收的影響。

但要注意:aspnet_state是以windows服務形式啟動並執行,所以請先確保127.0.0.1對應的機器上該服務已經啟動

另外,我們也必須意識到:雖然StateServer模式下session會穩定很多,但是效能相對InProc而言是有損耗的(大概在15%~25%左右),因為系統內部要將session值序列化以後,儲存到aspnet_state進程映射的記憶體中,讀取的時候還要還原序列化。

這種模式還有一個優點:如果tcpip=127.0.0.1:42424中的IP地址指定為另外一台伺服器,意味著可以將session儲存在web伺服器以外的機器上。

 

session資訊甚至還能儲存到SqlServer資料庫中:

進入vs命令列模式,輸入以下命令:

即aspnet_regsql -S 資料庫執行個體名 -ssadd -U 串連使用者名稱

注意:資料庫伺服器得先啟動Sql Server代理服務

該命令運行後,將會自動建立一個AspState資料庫,同時會在tempdb資料庫下建立二張表ASPStateTempApplications與ASPStateTempSessions

對應的web.config配置為:

<sessionState mode="SQLServer" sqlConnectionString="data source=JIMMYT61P;uid=sa;pwd=***"></sessionState>

注:如果想把表直接建立在資料庫ASPState中,剛才的命令列中,再加一個參數 -sstype p ,即:

aspnet_regsql -S 資料庫執行個體名 -ssadd -sstype p -U 串連使用者名稱

同樣SqlServer模式在儲存讀取Session資料時,相對InProc模式也會有效能損耗(大約在25%左右),但利用SqlServer能實現Session資料的持久儲存.

 

最後再來看看mode中的另外二個值: Off與Custom

Off 相當于禁用了session,就不多說了

Custom 允許開發人員自己定義Session如何儲存,相當於提供了一個可供編程的開發介面(我從來沒用過,所以...也談不出很深的道道來,呵呵)

 

綜合一下:

InProc效能最高,但是有可能會使session無故丟失,而且這種模式無法適用於web伺服器叢集或負載平衡情境(因為多台伺服器之間無法實現Session同步),StateServer與SqlServer可應用於web伺服器叢集情境,但是效能有所降低;如果希望Session能持久化儲存,SqlServer是唯一的內建方案。

 

最後談點個人經驗:

一般情況下,我傾向於使用cookie,從而減少對伺服器資源的消耗,但是這也要找一個平衡點,因為服務端代碼中要得到用戶端的cookie,也就意味著cookie檔案必須通過瀏覽器傳遞到伺服器,同樣會消耗網路頻寬。

另外:在一些部落格系統中,比如使用者寫文章時,如果中途離開了下,然後繼續寫,等到儲存時會發現session已經失效,頁面跳到登入頁,辛苦打了N多字卻沒了!這時可考慮用代碼一直維繫session,即麒麟兄弟的心跳思想:讓你的網站"心跳"起來 ,或者用ajax每隔幾分鐘自動儲存一次

再者:從安全性上講,偽造session要比cookie難得多,相對更安全一些。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.