六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

ASP.NET 中 Session 完成原理淺析 [2] 狀態(tài)管理器

[摘要]狀態(tài)管理本來是一件很美好的事情,嘿嘿,只可惜總是有些廠商在實現(xiàn)的時候考慮得不那么周全。例如 MS 在 ASP 中的狀態(tài)管理實現(xiàn)就比較爛,因為只實現(xiàn)了一個進程內的基于內存的狀態(tài)管理,故而存在很多問題:...
狀態(tài)管理本來是一件很美好的事情,嘿嘿,只可惜總是有些廠商在實現(xiàn)的時候考慮得不那么周全。例如 MS 在 ASP 中的狀態(tài)管理實現(xiàn)就比較爛,因為只實現(xiàn)了一個進程內的基于內存的狀態(tài)管理,故而存在很多問題:

1.所有的 Session 數(shù)據(jù)都保存在 Web 服務的進程中,會造成服務器支持會話數(shù)量受到服務器內存資源的限制問題,同時也因為大量非活動會話導致內存被無效占用。
2.服務器進程崩潰會導致所有的會話數(shù)據(jù)丟失。
3.會話無法跨進程或在負載均衡情況下使用,除非負載均衡技術保障同一用戶每次都能被路由到同一機器上。就算這樣也無法保障服務器崩潰造成的會話數(shù)據(jù)丟失。
4.需要 Cookie 的支持,而現(xiàn)在因為安全性問題,很多人在瀏覽器中關閉了 Cookie 和 js 的支持。

為此 ASP 的使用者不得不自己手工將會話信息以會話 ID 為主鍵同步到外部數(shù)據(jù)庫中,以緩解類似問題。

而在 ASP.NET 中,因為設計時就考慮了這些問題,能夠避免這些限制:

1.支持進程外的狀態(tài)管理,通過獨立狀態(tài)管理服務或 SQL Server 狀態(tài)服務器管理會話狀態(tài)
2.支持不使用 Cookie 的狀態(tài)維護,通過在 URL 中自動增加會話 ID 來避免使用 Cookie
3.通過獨立的狀態(tài)管理服務或SQL Server 狀態(tài)服務器支持負載均衡時同步使用會話信息

實現(xiàn)這些特性的正是上節(jié)提到的 SessionStateModule.InitModuleFromConfig 函數(shù)中,根據(jù) sessionState 標記的 mode 屬性選擇的四種不同的狀態(tài)管理器實現(xiàn)。


以下內容為程序代碼:

<system.web>
<sessionState mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
stateNetworkTimeout="10"
sqlConnectionString="data source=127.0.0.1;Integrated Security=SSPI"
cookieless="false"
timeout="20" />
</system.web>



Off 模式禁止會話管理,同時 ASP.NET 還允許通過在頁面中以 EnableSessionState 屬性細粒度管理頁面的會話支持狀態(tài)
以下內容為程序代碼:

<%@ Page EnableSessionState=" True False ReadOnly" %>



InProc 模式兼容以前 ASP 的策略,在 ASP.NET 同一進程空間內實現(xiàn)基于內存的會話狀態(tài)管理,速度最快但受到與 ASP 相同的限制;
StateServer 模式通過 ASP.NET 獨立安裝的 ASP.NET State Service 服務(aspnet_state.exe),以 stateConnectionString 指定的IP和端口響應會話狀態(tài)服務;
SQLServer 模式則通過 sqlConnectionString 指定的 SQL Server 服務器,以內存臨時表(以 InstallSqlState.sql建庫,使用 tempdb 內存數(shù)據(jù)庫)或獨立表(以InstallPersistSqlState.sql 監(jiān)控,使用獨立的 ASPState 庫)維護會話狀態(tài)。

這四種不同的狀態(tài)管理器,在性能上據(jù)《Performance Tuning and Optimizing ASP.NET Appliation》一書的測試,相對值如下:

以下為引用:

Table 4-1: Normalized TTLB(Time to Last Byte) by Session State Mode (in Milliseconds per 100 Requests)

CONCURRENT BROWSERS MODE = OFF MODE = INPROC MODE = STATESERVER MODE = SQLSERVER
1 7.81 4.54 8.27 8.47
5 28.28 20.25 27.25 29.29
10 89.38 46.08 77.29 85.11


Table 4-2: Average Requests per Second by Session State Mode

CONCURRENT BROWSERS MODE = OFF MODE = INPROC MODE = STATESERVER MODE = SQLSERVER

1 18.86 24.17 18.31 18.11
5 21.66 25.74 21.54 21.34
10 17.23 23.8 18.11 17.6




可以看到,無論是從 TTLB 還是每秒平均請求數(shù)來說,進程外狀態(tài)管理器的性能都是可以令人接受的,當然還需要針對狀態(tài)管理情況在編寫代碼時做相關優(yōu)化。不過要使用進程外狀態(tài)管理器,則保存在會話中的對象受到必須提高二進制序列化支持的限制。

從使用角度來看,狀態(tài)管理器實際上都是由上節(jié)提到的 HttpSessionModule 建立管理,并通過 HttpSessionState 接口提供訪問的,結構如下圖:


MSDN 上的 Underpinnings of the Session State Implementation in ASP.NET 一文非常詳細的解釋了幾種不同狀態(tài)管理器的原理和使用,這兒就不羅嗦了。

從實現(xiàn)角度來看,上節(jié)中提到的 SessionStateModule.InitModuleFromConfig 函數(shù),根據(jù)配置文件中狀態(tài)管理器的模式,分別建立 System.Web.SessionState.InProcStateClientManager, System.Web.SessionState.OutOfProcStateClientManager 和 System.Web.SessionState.SqlStateClientManager 三類狀態(tài)管理器的實例。他們都繼承自 System.Web.SessionState.StateClientManager 抽象基類,并通過 System.Web.SessionState.IStateClientManager 接口向 HttpApplication 提高狀態(tài)管理服務。

IStateClientManager 接口是狀態(tài)管理器的統(tǒng)一管理接口,主要提供以下功能:
以下內容為程序代碼:

internal interface System.Web.SessionState.IStateClientManager.IStateClientManager
{
// 配置管理狀態(tài)管理器
void ConfigInit(SessionStateSectionHandler.Config config, SessionOnEndTarget onEndTarget);
// 保存 SessionStateModule 實例供后面使用
void SetStateModule(SessionStateModule module);
void ResetTimeout(string id);
void Dispose();

void Set(string id, SessionStateItem item, bool inStorage);

// 維護狀態(tài)管理器內容
IAsyncResult BeginGet(string id, AsyncCallback cb, object state);
SessionStateItem EndGet(IAsyncResult ar);

IAsyncResult BeginGetExclusive(string id, AsyncCallback cb, object state);
SessionStateItem EndGetExclusive(IAsyncResult ar);
void ReleaseExclusive(string id, int lockCookie);
}



ConfigInit 方法主要在初始化狀態(tài)管理器時通知其根據(jù)配置進行初始化工作,并將負責會話狀態(tài)清除的 SessionOnEndTarget 對象實例綁定到會話管理器(我們后面討論會話狀態(tài)管理實現(xiàn)時詳細討論)。對 OutOfProcStateClientManager 和 SqlStateClientManager 來說,在此階段還會初始化與外部服務器的連接,并通過一個 System.Web.Util.ResourcePool 實例,提供基于時間策略的資源池來維護連接;
ResetTimeout 方法重置指定 Session 的超時時間;對 InProcStateClientManager 來說,這個超時時間是通過 System.Web.Caching.CacheInternal 類型實現(xiàn)的緩存對象來使用的; OutOfProcStateClientManager 直接通過 MakeRequest 函數(shù)構造請求發(fā)給外部獨立的狀態(tài)管理器執(zhí)行; SqlStateClientManager 則調用存儲過程 TempResetTimeout 更新 ASPStateTempSessions 表的過期時間 Expires 字段;
Dispose 方法是否狀態(tài)管理器的資源,落實到代碼就是對 OutOfProcStateClientManager 和 SqlStateClientManager 中資源池的釋放;

Set 方法則將指定的 SessionStateItem 存儲到 id 相關的會話數(shù)據(jù)中,并根據(jù) inStorage 指定的對象狀態(tài),決定在發(fā)生異常的情況下是否釋放對此會話的鎖。與 ResetTimeout 的實現(xiàn)類似,OutOfProcStateClientManager 發(fā)送請求給外部獨立的狀態(tài)管理器;SqlStateClientManager 調用存儲過程 TempUpdateStateItemXXX 更新會話狀態(tài)表 ASPStateTempSessions 中的過期時間 Expires 字段、鎖定狀態(tài) Lock 字段、以及狀態(tài)信息 SessionItemShort/SessionItemLong (分別保存7000字節(jié)以下或之上的數(shù)據(jù))。如發(fā)生異常并設置 inStorage 標記,則先調用 TempReleaseStateItemExclusive 釋放會話鎖。

對狀態(tài)管理器中數(shù)據(jù)的獲取較為復雜,IStateClientManager 接口使用的是異步調用的模式,并為提高效率將獨占的獲取數(shù)據(jù)單獨拿出來。狀態(tài)管理器實現(xiàn)類通過通用基類 System.Web.SessionState.StateClientManager 實現(xiàn)的幾個工具方法,將數(shù)據(jù)獲取操作異步化。再最終由實現(xiàn)類通過 Get 和 GetExclusive 方法完成操作。獲取數(shù)據(jù)的方法 InProcStateClientManager 通過緩存;OutOfProcStateClientManager 通過請求;SqlStateClientManager 通過 TempGetStateItemXXX 存儲過程完成。

在了解了 SessionStateModule 控制的狀態(tài)服務器的實現(xiàn)和使用方法后,我們來看看上層的 HttpSessionState 是如何使用的。



Mandeep S Bhatia 的 ASP.NET Session Management Internals 介紹了 HttpSessionState 內部完成狀態(tài)信息管理的原理。HttpSessionState 的 Item 屬性實際上是通過 SessionDictionary 實例實現(xiàn)的。
以下內容為程序代碼:

public sealed class HttpSessionState : ...
{
private SessionDictionary _dict;

public object this[string name]
{
get
{
return _dict[name];
}
set
{
_dict[name] = value;
}
}
}



而此 SessionDictionary 實例與 HttpSessionState 實例的構造,都是在前面提到的完成會話構造的 SessionStateModule.CompleteAcquireState 方法中完成的:
以下內容為程序代碼:

public sealed class SessionStateModule : IHttpModule
{
private string _rqId;
private SessionDictionary _rqDict;
private HttpStaticObjectsCollection _rqStaticObjects; // 靜態(tài)對象,通過頁面中 <object Runat="Server" Scope="Session"/> 標記設置
private int _rqTimeout;
private bool _rqIsNewSession;
private bool _rqReadonly;
private HttpContext _rqContext;
private SessionStateItem _rqItem;

private void CompleteAcquireState()
{
if (_rqItem != null)
{
if (_rqItem.dict != null)
{
_rqDict = _rqItem.dict;
}
else
{
_rqDict = new SessionDictionary();
}
_rqStaticObjects = ((_rqItem.staticObjects != null) ? _rqItem.staticObjects :
_rqContext.Application.SessionStaticObjects.Clone());
_rqTimeout = _rqItem.timeout;
_rqIsNewSession = false;
_rqInStorage = true;
_rqStreamLength = _rqItem.streamLength;
}
else
{
_rqDict = new SessionDictionary();
_rqStaticObjects = _rqContext.Application.SessionStaticObjects.Clone();
_rqTimeout = SessionStateModule.s_config._timeout;
_rqIsNewSession = true;
_rqInStorage = false;
}
_rqDict.Dirty = false;

_rqSessionState = new HttpSessionState(_rqId, _rqDict, _rqStaticObjects, _rqTimeout, _rqIsNewSession,
SessionStateModule.s_config._isCookieless, SessionStateModule.s_config._mode, _rqReadonly);

_rqContext.Items.Add("AspSession", _rqSessionState);

}
}



這兒涉及到的幾個字段,基本上都能跟 HttpSessionState 提供的公共屬性對應起來。需要注意的是 HttpSessionState.StaticObjects 是通過 ASP.NET 頁面上的 <object Runat="Server" Scope="Session"/> 類似標記靜態(tài)定義的;_rqReadonly 則是前面提到的 <%@ Page EnableSessionState=" ReadOnly" %> 標記設置的。

至此,狀態(tài)管理器的使用與實現(xiàn)方法基本上分析完成,下面整理一下其使用流程:

1.構造:HttpApplication 在初始化過程中調用 InitModules 初始化配置文件 Machine.config 中注冊的實現(xiàn)了 IHttpModule 接口的 HTTP 模塊;其中 SessionStateModule 作為模塊之一被構造并初始化;其 InitModuleFromConfig 方法根據(jù)配置文件中狀態(tài)管理器的相關配置,構造并初始化相應的狀態(tài)管理器;并根據(jù)各種條件調用 CompleteAcquireState 方法完成 HttpSessionState 的構造工作。
2.使用:HttpSessionState 通過 SessionDictionary 實現(xiàn)其 Item 屬性的狀態(tài)數(shù)據(jù)管理;SessionDictionary 本身由 SessionStateModule.OnReleaseState 在適當?shù)臅r候寫回狀態(tài)管理器;其他維護操作也是通過 SessionStateModule 調用狀態(tài)管理器的 IStateClientManager 接口完成的。
3.實現(xiàn):狀態(tài)管理器從抽象基類 StateClientManager 獲得異步調用的封裝;通過 IStateClientManager 接口提供給 SessionStateModule 管理其初始化、釋放和管理的接口。

雖然 ASP.NET 做了很多工作,但個人感覺還遠遠不夠。例如 InProc/OutOfProc 實際上都是在內存中,只是解決了一個可靠性和數(shù)據(jù)集中同步的問題;SQL Server 雖然能夠解決容量、可靠性和數(shù)據(jù)集中同步的問題,但效率又受到影響。這方面 .NET 應該向 Java 好好學習一下,例如 Java 下 EHCache 和 OSCache 都提供了平滑的可配置二級(內存/硬盤)緩存介質切換,并且后者還提供了對負載均衡的簡單支持,此外還有 JBoss 等實現(xiàn)的基于 IP 多播等實現(xiàn)技術的負載均衡緩存實現(xiàn)等等,都遠遠超出了 ASP.NET 提供的緩存機制所考慮到的范圍。雖然 ASP.NET 也有獨立的緩存機制,MS 也提出了 Cache Application Block 的參考實現(xiàn),不過還是任重而道


主站蜘蛛池模板: 亚洲va久久久噜噜噜久久天堂 | 亚洲国产欧美在线人成精品一区二区 | 天天干天天拍天天射天天添天天爱 | 一二三四免费观看在线影视大全 | 日韩欧美一及在线播放 | 日韩欧美精品在线视频 | 日韩中文字幕视频在线观看 | 制服丝袜自拍偷拍 | 日韩一区精品 | 日韩欧美黄色 | 婷婷色吧| 色视频一区二区三区 | 亚洲第二十页 | 天堂bt| 四虎影院精品在线观看 | 亚洲地址一地址二地址三 | 天堂网中文字幕 | 欧美午夜不卡在线观看最新 | 欧美特黄一区二区三区 | 视频在线一区二区 | 日本三级2020 | 中文字幕日韩精品亚洲七区 | 四虎国内精品一区二区 | 最新网址在线观看 | 日韩视频在线观看 | 香港三级理论在线影院 | 中文字幕成人免费视频 | 亚欧色视频在线观看免费 | 青青伊人影院 | 青青草原成年网站免费观看 | 一区二区三区视频免费观看 | 一二三四在线观看免费高清网 | 欧美视频高清 | 亚洲欧美视屏 | 中文字幕日韩精品中文区 | 中文字幕第23页 | 亚洲 欧美 国产 日韩 制服 bt | 淫片a武则天 | 午夜视频在线观看www中文 | 欧美性猛交xxxx乱大交be | 色五月天天 |