欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ASP.NET下跨应用共享Session和使用Redis进行Session托管

程序员文章站 2022-11-28 11:31:19
 在之前的博客中,我说到了session的共享问题,其中说到了web farm和web garden两种情况下session的处理。在asp.net提供的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的工作就做完了。