ASP.NET下跨應用共享Session和使用Redis進行Session托管


         在之前的博客中,我說到了Session的共享問題,其中說到了Web Farm和Web Garden兩種情況下Session的處理。在ASP.NET提供的Session處理方法中,有以下四種模式:

1、  InProc模式

這是ASP.NET默認的Session管理模式,在應用進程內維護Session。

2、  StateServer模式

這是在服務器裝了.NET環境后自帶的一個StateServer服務,在應用進程外管理Session,可以進行多應用間的Session共享,在我看來這一模式最為適用於Web Garden模式。這在之前的博客里講過。

3、  SQLServer模式

這是利用SQLServer進行Session的托管。其優點在於可以利用SQLServer的優勢處理海量Session,在應用進程外、可持久化、安全性高等優點。SQLServer模式非常適用於Web Farm環境

4、  Custom模式

這是自定義模式,發揮空間很大,在擁有Provider的情況下,可以利用這一模式進行發揮,利用各種各樣的數據存儲程序進行Session管理。今天這篇博客主要討論這一模式下的Redis托管Session的應用。

        

         在使用StateServer、SQLServer模式中,我遇到過一個很棘手的問題:Session Name的控制問題。在ASP.NET處理這個問題時,為了保證應用的統一,ASP.NET會對托管在IIS上的每個應用ID做hash並作為存儲在數據庫中SessionId的前綴。這就留下了一個問題,如果在一台服務器上有多個應用,則必須保證每個應用的ID在不同服務器上完全相同,否則就會出現Session無法共享的悲劇。而我們進行應用部署的時候為了容災,在一台服務器放多個應用是完全有可能的,那么一定要注意IIS中應用ID的一致。更麻煩一點的用法是利用反射修改SessionId生成規則或者修改數據庫存儲過程,強制前綴統一,這個方法較為麻煩,而且在一定程度上降低了應用的性能,故不推薦。

         今天我推薦的是利用第三方Provider托管Session。第三方Provider很多,例如Oracle,Memecache,Redis,Mongodb,都有很多Provider,如果你對自己的技術信得過,也能自己繼承System.Web.SessionState. SessionStateStoreProviderBase這個類進行擴展。

         而我使用的是這個Provider:Harbour.RedisSessionStateStore,

GitHub:https://github.com/TheCloudlessSky/Harbour.RedisSessionStateStore

         這個Provider是在ServiceStack.Redis作為Redis Driver的基礎上進行開發的。

         使用非常簡單,首先,搭建好你的Redis環境,將Harbour.RedisSessionStateStore、ServiceStack.Redis添加引用,然后修改Web.config的配置如下:

       
 <system.web>
  <sessionState mode="Custom" customProvider="RedisSessionStateProvider">

    <providers>

      <clear />

      <add name="RedisSessionStateProvider"

           type="Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider"

           host="localhost:6379" clientType="pooled" />

    </providers>

  </sessionState>

</system.web>

 

其中最為關鍵的是host屬性,指向了你的Redis服務的IP/端口。在使用Redis中,你也可以為Redis配置密碼,而配置文件中需要修改host屬性為:password@localhost:6379。clientType默認設為pooled連接池模式。若不使用連接池模式則修改為其他字符串(空也視為pooled模式)。

    這個Provider有一個特點,不針對應用ID為Session加前綴,這正是我所需要的特性,更方便多個系統之間的Session共享。接下來,配置Cookie域,將需要共享Session的應用全設在同一個頂級域名的域下:

    

  <system.web>

       <httpCookies domain="cnblogs.com"/>

    </system.web>

 

    如此這般使用Redis托管Session的工作就做完了。

 

=========================增加注意事項=====================

Harbour.RedisSessionStateStore這一個庫依賴於ServiceStack.Redis進行Redis操作,但是只支持到ServiceStack.Redis 3的版本,4的版本不支持!作者在Nuget上的包沒有做這一依賴限制,所以Nuget直接引用的話會出問題。把ServiceStack.Redis換為3.X就好了,我做了一個分支,支持4的版本,請求並入master,但是作者不同意,他原話是醬紫的:I do not plan to support v4 of SS.Redis with this library because of the non-free change~所以使用中出現問題請注意這個原因。

    如有錯誤,歡迎大家指正,歡迎轉載,但請注明出處。


免責聲明!

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



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