在之前的博客中,我说到了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~所以使用中出现问题请注意这个原因。

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

ASP.NET下跨应用共享Session和使用Redis进行Session托管的更多相关文章

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

    在之前的博客中,我说到了Session的共享问题,其中说到了Web Farm和Web Garden两种情况下Session的处理.在ASP.NET提供的Session处理方法中,有以下四种模式: 1. ...

  2. springboot项目中的普通Session和使用redis存储session

    普通session: session store type使用来存放session的存储方式,目前Spring boot中只支持Redis方式, 由于本应用暂无需将session放入redis的需求, ...

  3. 分布式集群环境下,如何实现session共享五(spring-session+redis 实现session共享)

    这是分布式集群环境下,如何实现session共享系列的第五篇.在上一篇:分布式集群环境下,如何实现session共享四(部署项目测试)中,针对nginx不同的负载均衡策略:轮询.ip_hash方式,测 ...

  4. 分布式集群Session共享 简单多tomcat8+redis的session共享实现

    ; i++) { str = str + session.getAttribute("name" + i) + "<br>"; } response ...

  5. 你的项目真的需要Session吗? redis保存session性能怎么样?

    在web开发中,Session这个东西一直都很重要,至少伴随我10年之久, 前一段时间发生一个性能问题,因为Redis session 问题,后来想想 其实我的项目session 是不需要的. 先看看 ...

  6. php session 保存到redis 实现session的共享

    1.redis安装肯定都会了,就不介绍了. 2.核心代码

  7. .Net分布式架构(二):基于Redis的Session共享

    一:Session简介 Session是什么呢?简单来说就是服务器给客户端的一个编号.当一台web服务器运行时,可能有若干个用户浏览正在运正在这台服务器上的网站.当每个用户首次与这台web服务器建立连 ...

  8. Spring Boot从入门到精通(七)集成Redis实现Session共享

    单点登录(SSO)是指在多个应用系统中,登录用户只需要登录验证一次就可以访问所有相互信任的应用系统,Redis Session共享是实现单点登录的一种方式.本文是通过Spring Boot框架集成Re ...

  9. 如何实现session跨服务器共享

    Session共享有多种解决方法,常用的有四种:客户端Cookie保存.服务器间Session同步.使用集群管理Session.把Session持久化到数据库. 1.客户端Cookie保存 以cook ...

随机推荐

  1. 【第六章】 springboot + 事务

    在实际开发中,其实很少会用到事务,一般情况下事务用的比较多的是在金钱计算方面. mybatis与spring集成后,其事务该怎么做?其实很简单,直接在上一节代码的基础上在相应的方法(通常是servic ...

  2. 【异常记录(九)】 System.Threading.ThreadAbortException: 正在中止线程

    报错如下: System.Threading.ThreadAbortException: Thread was being aborted. at System.Threading.Thread.Ab ...

  3. UVa 11572 唯一的雪花(滑动窗口)

    https://vjudge.net/problem/UVA-11572 题意:输入一个长度为n的序列A,找到一个尽量长的连续子序列,使得该序列中没有相同的元素. 思路:很简单的题,也没啥好解释的了. ...

  4. LoadRunner测试流程

    使用LoadRunner 完成测试一般分为四个步骤: 2 Vvitrual User Generator 创建脚本 创建脚本,选择协议 录制脚本 编辑脚本 检查修改脚本是否有误 3 中央控制器(Con ...

  5. H5图片预览、压缩、上传

    目标实现: 1.选择图片, 前端预览效果 2.图片大于1.2M的时候, 对图片进行压缩 3.以表单的形式上传图片 4.图片删除 预览效果图: 代码说明: 1.input:file选择图片 <!- ...

  6. Java jdbc访问sqlserver,oracle数据库 DEMO

    1.JDBC访问Oracle数据库 public class Jdbc_Oracle { // 静态代码块,只会执行一次,类似C#静态构造方法 static { try { // 加载数据库驱动一次 ...

  7. GRASP (职责分配原则)

    要学习设计模式,有些基础知识是我们必须要先知道的,设计模式是关于类和对象的一种高效.灵活的使用方式,也就是说,必须先有类和对象,才能有设计模式的用武之地,否则一切都是空谈,那么类和对象是从那冒出来的呢 ...

  8. php5.4 的 arm 交叉编译

    ./configure --prefix=/h1root/usr/php --host=arm-linux --enable-libxml --with-mysql=mysqlnd --with-my ...

  9. Java EE、Java SE和Java ME

    Java SE=Java Standard EditionJava EE=Java Enterprise EditionJava ME=Java Mobile Edition SE主要用于桌面程序,控 ...

  10. Windows7安装JDK的环境变量设置javac不是内部命令或外部命令

    转自:http://bbs.gfan.com/android-5941970-1-1.html Windows7安装JDK的环境变量设置 Windows7 X64安装“jdk-6u26-windows ...