• 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~所以使用中出现问题请注意这个原因。

        如有错误,欢迎大家指正,欢迎转载,但请注明出处。

  • 相关阅读:
    (OK) Android graphic (12)—display上层相关概念、关系
    (OK) Android系统启动-SystemServer下篇
    (OK) Android系统启动-SystemServer上篇
    (OK) Android 5 SystemServer 各个系统Manager-startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY)
    Android 6.0 源码分析
    (OK) android6.0源码分析之Runtime的初始化
    (OK) Android的JNI_OnLoad简介与应用
    (OK) Android架构实例分析之注册hello HAL的JNI方法表
    (OK) Android的NDK开发(1)————Android JNI简介与调用流程
    (OK) android-5.0 sensor工作原理—sensorservice的启动(二)
  • 原文地址:https://www.cnblogs.com/UliiAn/p/3554863.html
Copyright © 2020-2023  润新知