ASP.NET中Session的sessionState 5種mode模式 (草稿)


有關session鏈接

有關session丟失的解決方案:

  1、http://m.2cto.com/kf/201702/593964.html

  2、http://www.blogjava.net/Hopes/articles/385313.html

ASP.NET 使用mode=”InProc”方式保存Session老是丟失,無奈改成StateServer 模式

session是工作在你的應用程序進程中的。asp.net進程、iis往往會在20分鍾之后重啟相關的應用程序,緩沖池滿了(例如100個之后)也會重啟,各種進程保護措施都會隨時重新啟動,因此InProc方式丟失session是很正常的事。csdn上明確告訴了這種模式只能保存“易失的、暫時的 ”變量,這是cache沒有之前的一種解決方案。而長期保持的數據就要保存在外部數據源中。狀態服務器就是一種進程外的數據源。

 

StateServer 模式的實質是,把Session 存放在一個單獨的進程里,此進程獨立於 aspnet_wp.exe 或 w3wp.exe 。啟用此服務后,在“任務管理器”中可以看到一個名為 aspnet_state.exe 的進程,下面開始說明一下設置的具體步驟:

1、 修改注冊表(關鍵步驟,如下圖)

運行 regedit → 打開注冊表 → 找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state \Parameters 節點 → 將 AllowRemoteConnection 的鍵值設置成“1”(1 為允許遠程電腦的連接,0 代表禁止)→ 設置 Port (端口號)

注意事項:

a)、若ASP.NET State Service 正在運行,修改注冊表內容后,則需要重新啟動該服務

b)、注意端口號的鍵值是以十六進制儲存的,可以使用十進制進行修改,42424 是默認的端口

c)、AllowRemoteConnection 的鍵值設置成“1”后,意味着允許遠程電腦的連接,也就是說只要知道你的服務端口,就可享用你的ASP.NET State Service,即把 Session 存放在你的電腦進程內,因此請大家慎用;鍵值為“0”時,僅有stateConnectionString 為“tcpip=localhost: 42424”與“tcpip=127.0.0.1:42424”的情況,方可使用ASP.NET State Service

2、 開啟 ASP.NET State Service

右鍵點擊“我的電腦”→ 管理 → 服務與應用程序 → 服務 → 雙擊“ASP.NET State Service” → 啟動(可設為“自動”)

說明:只要安裝了 .Net Framework ,都擁有此服務。

3、 更改 Web.config

打開 Web.config → 找到 <sessionState> 節點內容

<sessionState

mode=”InProc”

stateConnectionString=”tcpip=127.0.0.1:42424″

sqlConnectionString=”data source=127.0.0.1;Trusted_Connection=yes”

cookieless=”false”

timeout=”20″ />

→ 將其改為以下內容

<sessionState mode=”StateServer” stateConnectionString=”tcpip=192.168.0.2:42424″ timeout=”20″ />



注意事項:
1、timeout=”20″為Session 20分鍾超時

2、IP 地址(可以是遠程計算機 IP、計算機名稱、域名)與端口號,端口號需與ASP.NET State Service 的服務端口一致

  3、http://m.2cto.com/kf/201702/593964.html

  4、http://m.2cto.com/kf/201702/593964.html

  5、http://m.2cto.com/kf/201702/593964.html

理解Session的幾種模式

 

一、寫在前面

  我們在使用ASP.NET開發的過程中,有時會進行數據存儲以實現請求前后的狀態保持(HTTP是無狀態保持的協議),而Session作為一種快速簡單易於實現的方式被我們經常使用,當然如果出於性能方面的考量,我們還是不建議往Seesion中塞入更多的東西,最好是不用Session。

  還有一點需要說明的是,Session實現的本質是在客戶端產生一個SessionId,具體的數據存儲在服務器端,客戶端通過SessionId來獲取服務器端的具體數據,那這個SeesionId是怎么保存在客戶端以及又是以什么方式來傳給服務器的呢?服務器端又是以什么方式保存Session的這些數據的呢?各種方式的優缺點又是什么?這就是本篇隨筆想要記錄的內容。

二、配置方式(Custom自定義模式博主未介紹,自行百度)

    <sessionState mode="Off|InProc|StateServer|SQLServer|Custom" 
              cookieless="true|false" 
              timeout="number of minutes" 
              stateConnectionString="tcpip=server:port" 
              sqlConnectionString="sql connection string" 
              stateNetworkTimeout="number of seconds" /> 

上面是Session在Web.config的配置方式,下面對各個節點做一些簡單的介紹

mode(設置將服務器的Session信息存儲到哪里)

  • Off表示設置為不使用Session功能;
  • InProc表示將Session存儲在進程內,這也是ASP中的存儲方式,這是默認值;
  • StateServer表示將Session存儲在獨立的狀態服務即ASP.NET State Service中;
  • SQLServer表示將Session存儲在SQL Server。

cookieless(設置客戶端的Session信息存儲到哪里)

  • true表示使用Cookieless模式(這表明SessionId將不再使用Cookie存儲了,而是將其通過URL存儲);
  • false表示使用Cookie模式,這是默認值。

從上面的設置配置中我們也可以發現Session和Cookie的關系:

  • 首先Session在客戶端的實現肯定是SessionId;
  • 默認這個SessionId是通過Cookie存儲的(比較安全);
  • 當然也可以通過URL來進行存儲,這樣Session和Cookie就沒有關系了,但是此種方式由於受URL長度限制以及明文傳送導致不安全而不被推薦使用。

timeout

Session過期時間設置,默認為20分鍾。

stateConnectionString 

如果設置將Session信息存儲在State Server中時,則需要此配置字符串表明服務器名稱和端口。

sqlConnectionString  

如果設置將Session信息存儲在SQL Server中,需此配置,表明數據庫的連接字符串,同時stateNetworkTimeout表明經過多少秒空閑后,斷開Web服務器與存儲狀態信息的服務器的TCP/IP連接的。默認值是10秒鍾。 

三、Session服務器端配置

1. InProc

  顧名思義,此種模式表示Session將會被保存在內存中,確切地說是保存在工作者進程中,對於IIS 5而言是aspnet_wp.exe,對於IIS 6而言是w3wp.exe,設置方式如下(Web.config)

<sessionState mode="InProc" cookieless="false" timeout="20"/>

 由於是直接保存在進程中,所以性能最好,但是經常會發生Session信息丟失,常見的導致進程重啟的可能情況為:

  • 配置文件中processModel標簽的memoryLimit屬性;
  • Global.asax或者Web.config文件被更改;
  • Bin文件夾中的Web程序(DLL)被修改;
  • 殺毒軟件掃描了一些.config文件;
  • 系統資源緊張進行資源回收導致IIS進程崩潰或重啟等。
  • 更多信息請參閱http://support.microsoft.com/kb/316148

2. State Server

  此種方式是將Session信息存儲在其它的進程中而不是IIS中,這樣就可以避免因IIS進程崩潰或重啟而導致的Session信息丟失。但是此種方式要求保存在Session的信息必須序列化,然后從Session中獲取的時候也要反序列化,這就導致性能有略微的損失。 

<sessionState mode="StateServer" cookieless="false" timeout="20"/>

  StateServer是本機的一個服務,可以在系統服務里看到服務名為ASP.NET State Service的服務,默認情況是不啟動的。當我們設定mode為StateServer之后,請把該服務的啟動模式設置為自動(這樣下次服務就可以隨機器而啟動)並手工將該服務啟動運行。這樣,我們就能利用本機的StateService來存儲Session了,除非電腦重啟或者StateService崩掉,否則Session是不會丟的。

<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" cookieless="false" timeout="20"/>

  此種配置和上面是一樣的(多了個stateConnectionString,換句話說127.0.0.1是默認本機IP,42424默認是該服務的訪問端口號,寫不寫效果是一樣的),都表示StateServer是在本機(注:StateServer模式是支持遠程主機服務的,配置類似與下面)

<sessionState mode="StateServer" stateConnectionString="tcpip=10.7.10.87:42424" cookieless="false" timeout="20"/>

  注:如果在啟動ASP.NET State Service服務時遇到問題0x8007277a 即無法啟動或初始化,請嘗試在命令行(CMD)中輸入netsh winsock reset(有可能是winsock的問題,所以需reset一下)

3. SQL Server

  此種方式是把Session信息保存在SQL Server的數據庫中,也需要序列化,性能有較大損失,但是Session一般不會發生丟失的情況,除非SQL Server宕機。而且此種方式也可以實現在Web Farm中的Session信息共享(上面兩種方式都不可以)。

<sessionState mode="SQLServer" sqlConnectionString ="data source=10.7.11.114; user id=session_user; password=Session@Pwd" timeout="20" />

3.1 安裝ASPState數據庫

在使用之前,我們要安裝配置對應的數據庫,而微軟給我們提供了一整套方案(你也可以選擇使用自己的數據庫或自己實現配置和管理)。ASP.NET 2.0版本后微軟提供了aspnet_regsql.exe工具可以方便的配置Session數據庫,該工具位於 Web 服務器上的"系統根目錄\Microsoft.NET\Framework\版本號"文件夾中.

使用舉例:

aspnet_regsql.exe -S . -U session_user -P Session@Pwd -ssadd -sstype p

-S參數:

表示數據庫實例名稱. 可以用"."表示本機,你也可以指定機器,如10.7.11.110等

-U和-P參數:

表示用戶名和密碼.

-E參數:

可以再-U –P 與 -E中選擇一組. –E表示以當前系統用戶通過windows身份驗證登錄數據庫, -U -P則是使用SqlServer用戶登錄數據庫.

-ssadd / –ssremove 參數:

-ssadd表示是添加Session數據庫, -ssremove表示移除Session數據庫.

sstype 參數:

選項

說明

t

將會話數據存儲到 SQL Server tempdb 數據庫中。這是默認設置。如果將會話數據存儲到 tempdb 數據庫中,則在重新啟動 SQL Server 時將丟失會話數據。

p

將會話數據存儲到 ASPState 數據庫中,而不是存儲到 tempdb 數據庫中。

c

將會話數據存儲到自定義數據庫中。如果指定 c 選項,則還必須使用 -d 選項包括自定義數據庫的名稱。

注意:如果sstype為t,則在下面的用戶權限賦予中要授予對tempdb的dbowner權限,否則將無法操作數據庫。 

3.2 建立連接數據庫 ASPState 的用戶,並為此用戶授權

  運行 SQL Server 的企業管理器 → 展開數據庫的安全性 → 右擊“登錄” → 新建“登錄” → 輸入“名稱” → 選擇 “SQL Server 身份驗證” → 輸入“密碼” → 指定“數據庫” → 點擊“數據庫訪問” → 勾選 “ASPState” → 選中“db_owner”角色 → 點擊“確定” → 再一次輸入“密碼” → 點擊“確定” 后即可建立 ASPState 的用戶,下面用命令實現:

--新建數據庫帳號 SessionStateUser ,默認登錄 ASPState
EXEC sp_addlogin 'SessionStateUser', '123456', 'ASPState'

use ASPState         --切換 DataBase

--將 SessionStateUser 授予 db_owner 的權限
exec sp_adduser 'SessionStateUser', 'SessionUser' ,'db_owner'

3.3 啟動SQL Server Agent

  自動運行Job ASPState_Job_DeleteExpiredSessions刪除過期的Session,否則數據庫中的數據將一直增長。

四、Session客戶端配置

  再次說明,Session的實現分為兩個部分:客戶端和服務器端,其中客戶端負責產生SessionId,服務器端負責保存具體的內容,這兒所說的Session客戶端配置其實是想說說關於SessionId的一些東西。

1. Session在客戶端是如何實現的?

  前面已經說過,Session在客戶端是通過產生SessionId來實現的,至於這個SessionId又是通過什么方式回傳之服務器從而獲得具體的Session內容,前面也略有說明,兩種方式:Cookie和Url,由於Url的方式會導致安全性問題,所以現在一般已不再使用此種方式。

  當系統是用Session的時候,系統將自動在客戶端產生一個Cookie,名稱為ASP.NET_SessionId,為了便於區別,我們暫且將此Cookie稱為Session Cookie

2. Session Cookie何時失效?

  和一般的Cookie一樣,默認是保存在瀏覽器的內存中,當瀏覽器關閉時失效,如果想此Cookie保存在本地磁盤,可通過設置其Expires屬性來達到,這種方式現在也被廣泛應用於網站的登錄,即用戶在登錄的時候選擇記住我或保持登錄一段時間,這樣當用戶下次再次訪問的時候就無需再次輸入用戶名密碼從而達到快速訪問的目的

HttpCookie httpCookie = new HttpCookie("ASP.NET_SessionId", Request.Cookies["ASP.NET_SessionId"].Value);
httpCookie.Expires = DateTime.Now.AddMinutes(20);
Response.Cookies.Add(httpCookie);
if (!string.IsNullOrEmpty(Request.Cookies["ASP.NET_SessionId"].Value))
{
    //...處理相關登錄驗證等信息
    Response.Redirect("Default.aspx?UserName=" + loginUser.UserName + "");
}

3. Session Cookie失效時Session失效嗎?

  答案當然是否定的,記住:Session Cookie和Session的失效沒有任何必然的聯系,因為它們失效的基准或者條件根本不一樣,Session Cookie的失效時間取決於客服端Cookie的失效時間,如果是保存在瀏覽器中,那么關閉瀏覽器Session Cookie就將失效,否則如果保存在本地磁盤,則取決於該Session Cookie設置的過期時間;而服務器端的Session是保存在服務器端的,它的失效與否與其服務器端的設置和Session的過期時間有關(下面的討論將忽略過期時間這個因數,你懂的),如果是InProc方式,那么當承載的IIS進程如果奔潰或重啟等都會丟失;如果是State Server,同樣如果這個Service宕掉,那Session也會丟失;而如果是SQL Server,則會寫入數據庫,如果你不刪除它,它甚至可以一直存在而永不丟失(事實是SQL Server Agent會自動運行一個Job刪除過期的Session);而當如果我們使用自定義的數據庫來保存Session時,你將獲得充分的控制。

4. Session Cookie何時產生?刷新頁面其值會改變嗎?

  牢記一點,只有當使用Session的時候才會產生Session Cookie。你也許會反問那為什么當配置Session模式為SQLServer時,就算沒有使用Session,也可以獲得ASP.NET_SessionId的值,即在Page_Load的時候執行方法Response.Write(Request.Cookies["ASP.NET_SessionId"].Value),會輸出值,我的猜測是雖然你可以獲得ASP.NET_SessionId值,但實際上並沒有真正產生Session Cookie,因為此時當我試圖通過HttpWatch(下面介紹的工具)來查看此Session Cookie的時候根本查不到,當然這也只是我的個人猜測而已,至於具體的內部機制還是不甚了解。

  當沒有使用Session的時候刷新頁面Session Cookie的值會變化嗎?答案是會的,測試方法如上,設置Session模式為SQLServer,在Page_Load的時候輸出Session Cookie的值,然后一直F5頁面即可,你會看到其值一直在變化,直到在代碼中明確地使用Session后便不再變化。

復制代碼
public partial class Login : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write(Request.Cookies["ASP.NET_SessionId"].Value);
    }

    protected void tbnLogin_Click(object sender, EventArgs e)
    {
        if (!string.IsNullOrEmpty(this.txtUserName.ToString()) && !string.IsNullOrEmpty(this.txtPassword.ToString()))
        {
            LoginUser loginUser = new LoginUser();
            loginUser.UserId = Guid.NewGuid().ToString("N");
            loginUser.UserName = this.txtUserName.Text;
            loginUser.UserPassword = this.txtPassword.Text;
            Session["LoginUser"] = loginUser;
        }
    }
}
復制代碼

5. Session Cookie如何查看

  如果設置了Session Cookie的過期時間,則此Session Cookie會保存在本地磁盤,一般是在目錄C:\Documents and Settings\user\Local Settings\Temporary Internet Files,此目錄可手工設置(Internet選項->常規->瀏覽歷史記錄中的"設置"選項->Internet臨時文件的"查看文件"選項)。

  如果沒有設置過期時間,則Session Cookie默認是保存在瀏覽器內存中的,Chrome瀏覽器默認支持查看Cookie,具體步驟如下:Tools - > Settings ->Show Advanced Settings -> Privacy -> Content Settings -> Cookies -> All cookies and site data,不過坑爹的是它只支持查看和刪除,不支持修改,如果你想修改的話,我們只能通過第三方插件來完成https://chrome.google.com/webstore/detail/fngmhnnpilhplaeedifhccceomclgfbg(Chrome Web Store瀏覽下載安裝即可)

  如果你使用的是IE瀏覽器,你也要通過安裝插件HttpWatch來查看(Firefox也適用)

五、Session的其它相關問題

1. 如何捕獲Global.asax中的Session_End()事件?

  • Session的服務器端模式必須配置為InProc,其它兩種模式(State Server或SQL Server)無法獲得Session_End事件;
  • Session過期時,此事件才會發生,與用戶是否關閉瀏覽器無關(關閉瀏覽器唯一可能的影響是此Session在客戶端部分產生的Cookie失效,而服務器端Session繼續存在,而且此時Cookie失效的前提也是把Cookie保存在瀏覽器中)

  另請注意:在Session_End()中如果試圖去使用Response或Request都是錯誤的,因為它們此時都已失效,不過你可以用記錄log的方法來獲取session失效的相關信息。

2. 如果提高客戶端Session Cookie的安全性?

  • 指定HttpCookie對象的HttpOnly屬性為true,此屬性用於標識一個Cookie是否可通過客戶端腳本訪問,true為可以,false為不可以,默認為false。設定的方式有兩種:編程或配置文件。注意此屬性並不能完全阻止客戶端在本地獲取cookies(上面已經介紹過如果獲取此session cookie),但是可以增加通過腳本直接獲取的難度。另外,Microsoft Internet Explorer 版本 6 Service Pack 1 和更高版本支持 Cookie 屬性 HttpOnly。
    HttpCookie sessionCookie = new HttpCookie("ASP.NET_SessionId");
    sessionCookie.HttpOnly = true;
    <httpCookies httpOnlyCookies="true" />
  • 對Cookies實行加密和用https傳輸:
    HttpCookie sessionCookie = new HttpCookie("ASP.NET_SessionId");
    sessionCookie.HttpOnly = true;
    sessionCookie.Secure = true;
    <httpCookies httpOnlyCookies="true" requireSSL="true" />

 

原文鏈接:http://www.cnblogs.com/panchunting/archive/2012/06/25/ASPNET_Session_Mode.html

 

 

 

 

 

 

 

 

 

 

1. sessionState的幾種mode模式

  在ASP.NET中Session的sessionState的4中mode模式:Off、InProc、StateServer及SqlServer。

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

2. Off模式

<sessionState mode="Off"></sessionState>

  關閉模式,即不需要使用Session。

單個頁面關閉Session:

<%@ Page EnableSessionState="false" %>

3. InProc模式(缺省模式)

<sessionState mode="InProc" cookieless="false" timeout="20"></sessionState>

mode設置為"InProc"時,Session直接存儲在IIS進程中。

  優點:獲取session狀態的速度快

  缺點:易丟失

mode為InProc可能造成Session丟失的情況:

  1>. ASP.NET進程(aspnet_wp.exe)、IIS進程(w3wp.exe)默認的20分鍾重啟應用程序;

  2>. 緩沖池填滿后重啟;

  3>. 進程保護措施重啟。

4. StateServer模式

mode設置為"StateServer"時,Session 存儲在單獨的內存緩沖區中,再由單獨一台服務器上運行的ASP.NET State Service(aspnet_state.exe)來控制這個緩沖區。

  優點:session狀態單獨存儲在一個進程中,不會因為iis或者應用的重啟而丟失狀態。

  缺點:

  1>. 由於是兩個不同的進程,獲取Session數據比InProc慢;

  2>. Session數據存儲在內存中,重啟ASP.NET State Service服務,Session數據將丟失。

<sessionState mode="StateServer" stateConnectionString="tcpip=tcpip=127.0.0.1:42424" cookieless="false" timeout="20"></sessionState>

  以上設置的ASP.NET State Service在127.0.0.1的42424端口(默認端口)上運行,要在服務器上改變端口,可編輯HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters注冊表項中的Port值。(打開注冊表方式:運行 regedit)

mode設置為"StateServer"需要注意:

  1>. 啟動ASP.NET State Service;

  2>. 如果stateConnectionString的值不是127.0.0.1或者localhost等代表本地地址的值,需要修改注冊表:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state \Parameters 節點 → 將 AllowRemoteConnection 的鍵值設置成“1”(1 為允許遠程電腦的連接,0 代表禁止)→ 設置 Port (端口號) 

5. SqlServer模式

  mode設置為"SqlServer"時,Session存儲在SQL Server數據庫中持久化保持,ASP.NET嘗試將會話數據存儲到由sqlConnectionString屬性(其中包含數據源以及登錄服務器所需的安全憑證)指定的SQL Server中。可應用場景:網絡負載均衡(NLB)環境。

設置SqlServer模式步驟:

  1>. 配置SQL erver創建ASPState數據庫

  創建ASPState數據庫,運行C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallSqlState.sql,可以通過SQL查詢分析器來執行語句,也可以使用sqlcmd來執行。

sqlcmd -S [server name] -U [user] -P [password] -i C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallSqlState.sql

此時SQLServer會創建數據庫ASPState,但是沒有表。

  若創建ASPState數據庫后要刪除,可以運行C:\Windows\Microsoft.NET\Framework\v4.0.30319\UninstallSqlState.sql,但要先停止w3svc進程。

net stop w3svc

  2>. ASPState創建表

aspnet_regsql.exe  -ssadd -sstype p -S [server name] -U [user] -P [password]

  運行cmd:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regsql.exe  -ssadd -sstype p -S (local) -U sa -P '1'

  此時數據庫中創建兩張表:ASPStateTempApplications、ASPStateTempSessions。

  3>. 設置sessionState

<sessionState mode="SQLServer" sqlConnectionString="data source=127.0.0.1;user id=sa;password=1" cookieless="false" timeout="20"></sessionState>

由於數據不存儲在本地內存,存儲Session狀態的對象需要進行序列化和反序列化,以便通過網絡傳給數據庫服務器,以及從數據庫服務器傳回。

原文鏈接:http://www.cnblogs.com/shiningrise/p/5628039.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM