天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

ASP.NET應用下基于SessionState的“狀態(tài)編程框架”解決方案

  在一個基于ASP.NET的Web應用程序中,我們通常使用SessionState保存基于某個客戶端的狀態(tài)信息。但是這種單純使用SessionState的編程方式具有很多局限,比如Session Item的Key值沖突,比如沒有一個有效的SessionState清除機制會為Web Server帶來內(nèi)存壓力。為了實現(xiàn)對客戶端狀態(tài)的有效管理,并提高應用開發(fā)效率,在很多年前我們的開發(fā)框架體系中就具有相應的一個叫做State的編程框架。最近我開始對其進行升級和重新設(shè)計,將實現(xiàn)原理和概要設(shè)計方面的東西寫出來與大家共享,希望對各位有些啟發(fā)。同時希望借此得到你們一些好的建議和意見,以便能夠充實我們的框架。于此同時,我寫了一個簡單的模擬程序?qū)崿F(xiàn)了該設(shè)計思想,有興趣的話可以通過這里下載該模擬程序。

  一、單純基于SessionState編程的局限性

  SessionState對于ASP.NET的開發(fā)者在熟悉不過了,我們可以通過它來存儲一些基于客戶端的狀態(tài)信息。從編程角度來說,SesssionState是依附和當前HttpContext的一個用于類似于字典的數(shù)據(jù)容器,我們通過鍵值對的方式進行Session Item的設(shè)置和獲取。但是這種單純地基于字典索引的編程方式,具有諸多局限:

  • 首先,這種弱類型的編程方式不便于快速開發(fā)需求。放入SessionState的值是一個System.Object類型的對象,在獲取的使用我們需要進行手工轉(zhuǎn)型;而Session Item的Key是手工指定的字符串,如果沒有對Key值進行有效的分配,在進行設(shè)置的時候很容易造成一個Key值得沖突,從而導致整個狀態(tài)的混亂;在獲取某個Session Item的時候,你指定的Key值可能和預先指定的不符。
  • 其次,統(tǒng)一的SessionState的清除機制的缺乏導致服務端內(nèi)存壓力。在默認的情況下(采用InProc會話模式),SessionState存儲于服務端內(nèi)存,如果過多、過大的Session Item常駐內(nèi)存,勢必會為服務端帶來內(nèi)存壓力。實際上,基于客戶端的所有的Session Item并不是在整個Session存續(xù)期間都是必須的,很多Session Item僅僅是在某幾個少數(shù)的Web頁面中使用。但是我們不能通過程序手工地將其從SessionState中刪除,因為我們不能確定該Session Item在那一刻不再需要,因為這往往取決于UI交互的行為。如果太多的低頻率使用的Session Item存在,并且它們還不小,服務端內(nèi)存過多地被占用必要導致性能的下降。
  • 最后,如果你采用State Server或者SQL Server會話管理模式,還會造成更多的性能問題。這樣的性能損失包括:Session Item的序列化和反序列化、序列化后的Session Item在Web Server和State Server或者SQL Server的網(wǎng)絡(luò)傳輸、針對State Server或者SQL Server的數(shù)據(jù)存取(保存和提取)等。

  實際上,我們的State框架還是建立在SessionState基礎(chǔ)之上,但是它能夠很好的解決上述的三大難題:

  • 通過配置為所有使用到的狀態(tài)項(狀態(tài)屬性名稱、數(shù)據(jù)類型等)提供結(jié)構(gòu)化的定義,并通過基于該結(jié)構(gòu)化配置提供的代碼生成使強類型編程成為可能。這比較類似于ASP.NET中Profile的配置和強類型編程的方式;
  • 提供狀態(tài)的后備存儲(Backing Storing)機制將低頻率使用的大對象從SessionState中移到相應的后備存儲(比如文件、數(shù)據(jù)庫)中,從而緩解服務端內(nèi)存壓力;
  • 提供靈活的后備策略定義方式以實現(xiàn)基于具體運行環(huán)境的最優(yōu)配置。后備策略主要包括兩方面的內(nèi)容,其一是怎樣的狀態(tài)項需要被后備存儲,其二采用怎樣的方式進行后備存儲。確定后備存儲狀態(tài)項的因素包括:自最近一次被訪問以來的超時時限(通過使用頻率判斷狀態(tài)項再次被使用的可能性);需要被后備存儲對象必須具有的最小字節(jié)數(shù)(后備存儲小對象毫無意義) ;以及狀態(tài)項的作用域(很多狀態(tài)項的作用范圍僅僅限于某一個相關(guān)的Web頁面,或者基于某個基地址)等。而具體采用的后備存儲方式?jīng)Q定于配置的“后備存儲器”,比如在我提供的例子中采用的是基于文件的存儲方式,你可以編寫基于數(shù)據(jù)庫的后備存儲器。

  二、通過狀態(tài)后備存儲機制解決Web Server內(nèi)存的壓力

  狀態(tài)的后備機制是整個狀態(tài)編程框架的核心。通過對所有狀態(tài)項的掃描,標記出所有需要進行后備存儲的狀態(tài)項。然后將它們進行序列化,并借助于指定的后備存儲器將它們存儲到相應的物理存儲介質(zhì)。最后,相應的狀態(tài)會從SessionState中刪除,從而緩解了Web Server的內(nèi)存壓力。除了將序列化的狀態(tài)對象進行后備存儲之前,后備存儲器還負責從相應的存儲介質(zhì)中提取狀態(tài)數(shù)據(jù)。

  簡單起見,我們并沒有在后臺運行一個實施后備檢測操作的引擎,而是直接通過事件注冊的方式讓每一個請求自動去觸發(fā)基于本會話的后備存儲,我們注冊的事件是HttpApplication的PostRequestHandlerExecute。出于性能的考慮,當事件PostRequestHandlerExecute被觸發(fā)的時候,并不是總是立即執(zhí)行后備狀態(tài)項的檢查。而是設(shè)置一個相鄰兩次后備檢查的間隔,只有超出這個間隔的情況下,才會進行真正地區(qū)檢查那些狀態(tài)向需要進行后備存儲了。狀態(tài)項的后備存儲緊接著在后備對象的檢查之后進行。

  我們通過一個具體的例子來進一步說明后備存儲的過程。如左圖(點擊看大圖)所示,在Web Server的IIS進程中的SessionState中維持著三個狀態(tài)項:Foo、Bar、Baz。當Web Server接收并執(zhí)行來自瀏覽器的HTTP請求后,PostRequestHandlerExecute事件的處罰激活了我們的后備檢查管理器,它發(fā)現(xiàn)狀態(tài)項Baz最近一次被訪問的時間到當前時間的間隔已經(jīng)超出了設(shè)置的超時時限,并且計算出該對象的總字節(jié)數(shù)超過了設(shè)定的下限,就會將該對象標記為后備存儲對象。在這種情況下,狀態(tài)項Baz的值,同它的Key一并進行序列化并進行后備存儲。最后將該Baz從SessionState中移除。

  如果該Web應用使用Web Farm部署方式,并采用了Sate Server或者SQL Server的會話模式,在同步到Sate Server或者SQL Server的時候,由于SessionState中缺少了Baz這個大對象,也會因為少了對它序列化、網(wǎng)絡(luò)傳輸和數(shù)據(jù)存取使性能得到相應的提升。

  三、后備存儲狀態(tài)項的“復蘇”

  被后備存儲的狀態(tài)項已經(jīng)不再存儲于SessionState中,但是并不意味著它已經(jīng)是所謂的垃圾對象,它們依然可以被再次訪問。在這種情況下,我們會通過我們指定的后備存儲器將相應的狀態(tài)值以字節(jié)數(shù)組的形式從存儲介質(zhì)中提取出來,進行反序列化后再次放到SessionState中,我個人將這種機制成為“后備對象的復蘇”。

  在對后備對象的復蘇機制進行進一步講解之前,我們需要了解一個前提:框架始終維護著每一個狀態(tài)項運行時信息,這些信息包括:狀態(tài)項最后一次被訪問的時間、狀態(tài)項的使用范圍、狀態(tài)項當前的存儲位置(SessionState或者BackingStore)、以及相關(guān)的后備策略信息等。這個列表放在SessionState中。

  右面所示的序列圖(點擊看大圖)反映了當我們的程序獲取某個狀態(tài)項時,狀態(tài)后備機制采用的處理流程:當接收到一個來自對某個狀態(tài)項的請求時,根據(jù)Key值獲取該狀態(tài)項當前的運行時信息。如果運行時信息反映它還存在于SessionState中(Location=Session),則直接從SessionState中返回,并更新它的運行時信息(最后一次被訪問時間)。

  如果該狀態(tài)項已經(jīng)進行了背后存儲(Location=BackingStore),則借助相應的后備存儲器從存儲介質(zhì)中對應的值以字節(jié)數(shù)組的形式提取出來。在完成反系列化后再次保存到SessionState中,并更新相應運行時信息(最后一次訪問時間和當前位置:BackingStore-〉Session)。最后返回反序列化后的具體狀態(tài)對象。

  四、狀態(tài)項后備策略的定義

  判斷一個存在于SessionState中的狀態(tài)項是否應該被后備存儲取決于以下三個方面,當同時滿足條件1和2,或者2和3的狀態(tài)項會被后備存儲

  • 針對該狀態(tài)項的最近一次訪問的事件到當前時間的間隔超過了設(shè)定的超時時限;
  • 狀態(tài)項的總的字節(jié)數(shù)超過了設(shè)定的需要進行后備存儲的下限;
  • 當前的請求的URL是否超出了設(shè)定的狀態(tài)作用的范圍。

  但是我們的狀態(tài)后備策略并沒有直接應用于單個的狀態(tài)項,而是應用于一個較大的粒度:狀態(tài)組——若干相關(guān)狀態(tài)項的組合。狀態(tài)組的結(jié)構(gòu)和應用在它上面的后備策略通過配置進行定義,下面的XML體現(xiàn)的配置大體上的結(jié)構(gòu)。

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <states>
   3:   <properties>
   4:     <property name="UserName" type="System.String"/>
   5:     <property name="Position" type="System.String"/>
   6:   </properties>
   7:   <group name="Profile" inactiveTimeout="00:10:00" minimunTotalBytes="1024" >
   8:     <property name="Age" type="System.Int32"/>
   9:     <property name="Address" type="System.String"/>
  10:   </group>
  11:   <group name="Product" inactiveTimeout="00:10:00" minimunTotalBytes="1024" scope="Page1, Page2,Page3" >
  12:     <property name="ProductId" type="System.String"/>
  13:     <property name="UnitPrice" type="System.Decimal"/>
  14:   </group>
  15: </states>

NET技術(shù)ASP.NET應用下基于SessionState的“狀態(tài)編程框架”解決方案,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 亚洲一区在线播放 | 综合久久久久久久综合网 | 中文无码乱人伦中文视频播放 | 麻婆豆腐传媒视频免费 | 午夜免费国产体验区免费的 | 精品国产美女AV久久久久 | 国产精品久久久久婷婷五月色 | 俄罗斯6一9泑女网站 | 色即是空之甜性涩爱 | 欧美亚洲另类图片 | 四房播播开心色播 | 被老总按在办公桌吸奶头 | 麻豆免费观看高清完整视频在线 | 免费网站在线观看国产v片 免费完整版观看 | 男人J桶进男人屁股过程 | 久久伊人天堂视频网 | 亚洲国产成人一区二区在线 | 亚洲精品一线二线三线无人区 | 后入式啪gif动态图 后入式狂顶免费视频 | 青青草狠狠干 | 在线 | 果冻国产传媒61国产免费 | 国产欧美一区二区三区在线看 | 日韩高清在线亚洲专区 | 久久综合久综合久久鬼色 | 国产精品成久久久久三级四虎 | 最新老头恋老OLDMAN | 正在播放黑人杂交派对卧槽 | 久久成人无码国产免费播放 | 亚洲精品久久久久中文字幕二区 | 精品一区二区三区AV天堂 | 中文字幕亚洲综合小综合在线 | 国产 亚洲 中文字幕 久久网 | 国产精品久久久久久无码专区 | 最近日本字幕MV免费观看在线 | 高中生高潮抽搐喷出白浆视频 | 不用播放器的黄 | 中文无码乱人伦中文视频播放 | CHESENGAY痞帅警察GV | 天天爽夜夜爽8888视频精品 | 出差无套内射小秘书 | 少妇被阴内射XXXB少妇BB |