亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

ASP.NET 中 Session 實現原理淺析 [2] 狀態管理

系統 3018 0

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

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

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

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

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

實現這些特性的正是上節提到的 SessionStateModule .InitModuleFromConfig函數中,根據 sessionState 標記的mode屬性選擇的四種不同的狀態管理器實現。
< system .web >
< sessionState mode ="InProc"
stateConnectionString
="tcpip=127.0.0.1:42424"
stateNetworkTimeout
="10"
sqlConnectionString
="datasource=127.0.0.1;IntegratedSecurity=SSPI"
cookieless
="false"
timeout
="20" />
</ system.web >

Off模式禁止會話管理,同時ASP.NET還允許通過在頁面中以EnableSessionState屬性細粒度管理頁面的會話支持狀態
<% @PageEnableSessionState = " True|False|ReadOnly " %>

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

這四種不同的狀態管理器,在性能上據《PerformanceTuningandOptimizingASP.NETAppliation》一書的測試,相對值如下:
以下為引用:

Table4-1:NormalizedTTLB(TimetoLastByte)bySessionStateMode(inMillisecondsper100Requests)

CONCURRENTBROWSERSMODE=OFFMODE=INPROCMODE=STATESERVERMODE=SQLSERVER
17.814.548.278.47
528.2820.2527.2529.29
1089.3846.0877.2985.11


Table4-2:AverageRequestsperSecondbySessionStateMode

CONCURRENTBROWSERSMODE=OFFMODE=INPROCMODE=STATESERVERMODE=SQLSERVER

118.8624.1718.3118.11
521.6625.7421.5421.34
1017.2323.818.1117.6


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

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


MSDN上的 UnderpinningsoftheSessionStateImplementationinASP.NET 一文非常詳細的解釋了幾種不同狀態管理器的原理和使用,這兒就不羅嗦了。

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

IStateClientManager接口是狀態管理器的統一管理接口,主要提供以下功能:
internal interface System.Web.SessionState.IStateClientManager.IStateClientManager
{
// 配置管理狀態管理器
void ConfigInit(SessionStateSectionHandler.Configconfig,SessionOnEndTargetonEndTarget);
// 保存SessionStateModule實例供后面使用
void SetStateModule(SessionStateModulemodule);
void ResetTimeout( string id);
void Dispose();

void Set( string id,SessionStateItemitem, bool inStorage);

// 維護狀態管理器內容
IAsyncResultBeginGet( string id,AsyncCallbackcb, object state);
SessionStateItemEndGet(IAsyncResultar);

IAsyncResultBeginGetExclusive(
string id,AsyncCallbackcb, object state);
SessionStateItemEndGetExclusive(IAsyncResultar);
void ReleaseExclusive( string id, int lockCookie);
}

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

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

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

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



MandeepSBhatia的 ASP.NETSessionManagementInternals 介紹了HttpSessionState內部完成狀態信息管理的原理。HttpSessionState的Item屬性實際上是通過SessionDictionary實例實現的。
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; // 靜態對象,通過頁面中<objectRunat="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頁面上的<objectRunat="Server"Scope="Session"/>類似標記靜態定義的;_rqReadonly則是前面提到的<%@PageEnableSessionState="ReadOnly"%>標記設置的。

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

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

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

ASP.NET 中 Session 實現原理淺析 [2] 狀態管理器


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久综合视频网 | 久久www免费人成精品 | 中国明星一级毛片免费 | 免费一极毛片 | 欧美成人看片黄a免费 | 亚洲资源站资源网在线 | 精品免费久久久久国产一区 | 久久九九免费视频 | 波多野结衣 一区二区 | 欧美日韩视频在线第一区 | 在线播放精品视频 | 爱爱免费播放视频在线观看 | 欧美日韩亚洲成人 | 日日草天天干 | 99热久久这里只精品国产 | 美女福利视频一区二区 | 欧美日本高清视频在线观看 | 久久国产高清视频 | 九九视频在线免费观看 | 国产亚洲综合久久 | 日本人一级大毛片 | 亚洲精品美女一区二区三区乱码 | 日本欧美一区二区三区在线观看 | 色偷偷亚洲女性天堂 | 精品中文字幕一区二区三区四区 | 亚洲精品久久久久午夜福 | 97在线观看中心 | 欧美 日韩 中文 | 黄色www| 日韩欧美亚洲国产精品字幕久久久 | 亚洲综合狠狠99婷婷 | 日日摸夜夜添夜夜添一区二区 | 中国女人内谢25xxxxx | 欧美午夜毛片a级在线 | 干天天 | 国产精品毛片一区二区三区 | 国产精品网页 | 97在线观看成人免费视频 | 一级片 在线播放 | 国产精品u任我爽爆在线播放 | 嫩模在线 |