分布式缓存扩展Session机制

 

为什么要把Session放在缓存中

  Session是我们常用的状态保持的对象,它通常会生成一个唯一的SessionId以Cookie的方式存在浏览器端,而Session本身会保存在服务器端。

  虽说我们用Session很方便的实现状态保持,但是Session也带来了很多弊端,下面我们一步一步来分析Session的一些弊端以及用什么方式去改变它:

  

  一、当mode="InProc"时:

    1.因为网站会因为各种原因重启,照成数据丢失,在线用户全部下线。

    2.Session保存的东西越来越多,占用服务器内存也就越来越大,服务器内存压力也会越来越大。

    3.Session存在服务器内存中,不能在多台服务器之间共享,扩展性收到了影响。

    -----解决方案:model="SQLServer"或者model="StateServer"...

  二、当model="SQLServer"或者model="StateServer"时:

    1.无论我们是否要使用SessionState,SessionStateModule一直在工作,每一个用户请求都会去处理SessionState,执行一些列的调用,其中还可能涉及到序列化和反序列化,这样造成了资源浪费,影响性能。

    2.每个用户对应一个SessionId,当一个用户同时打开两个页面的时候、或者一个页面中夹杂着IFrame、或者带着异步请求,这样算属于单个用户并发吧?!HttpHandler处理的时候是会对Session进行加锁的,当一个页面处理慢的时候会锁住当前的Session,后面的页面是不是也在等待当前Session的释放,就这样就照成一个问题——Session影响并发(单个用户并发)。虽说这种情况很少会出现,但是我们在处理一些特殊请求的时候,确实需要注意一下这个细节。对于上面所说的相信大家都有所理解,Session影响并发,可能没有太过关注过,下面举个例子试一试是不是这样的情况!

    先创建一个主窗体,三个父窗体,我注册了HttpModule来看一下执行的流程,Test_2页面线程睡眠5秒...

    

    在未使用Session的情况下...

    

    

     然后我在主窗体后台类中使用了Session    Session["test"]="test"; 会发现Test_3被阻塞了...

    

    

    解决方案:使用分布式缓存,最近有很多比较火热的分布式缓存系统,如:Memcached、Redis...

    因为Redis可以实现数据持久化,支持多重数据类型,可能应用场景更广泛一些,所以之前用了Redis,这次就那Redis来做例子,不过其他的实现方式也一样一样了...

    

  ------------------------------------------------------------------------------------------------------------------------------------------------------

    首先分析一下我们怎么来设计这个Session,我的想法是每个SessionId对应一个Dictionary<string,Object>,SessionId用Guid表示,也是以Cookie的形式发送在客户端,Session为键,Dictionary为值存放在Redis里...

    Session——SessionId{Dictionary<string,Object>}

          SessionId{Dictionary<string,Object>}

          SessionId{Dictionary<string,Object>}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

//使用Redis的命名空间
namespace ServiceStack.Redis
{
  //把Session作为Redis的扩展方法: 三要素——静态类、静态方法、this关键字
public static class RedisHelper
{
//private static RedisClient Redis = new RedisClient("127.0.0.1", 6379);
    
//设置Session
public static bool SetSession(this RedisClient Redis, string key, object value)
{
var requestCookie = HttpContext.Current.Request.Cookies["SessionId"];
string sessionId;
if (requestCookie == null)
{
sessionId = Guid.NewGuid().ToString();
}
else
{
sessionId = requestCookie.Value;
} Redis.Expire(sessionId, 20 * 60);
HttpContext.Current.Response.SetCookie(new HttpCookie("SessionId", sessionId));
if (Redis.Exists(sessionId) == 1 ? true : false)
{
var newDir = Redis.Get<Dictionary<string, object>>(sessionId) as Dictionary<string, object>;
if (newDir == null)
{
return false;
}
if (newDir.ContainsKey(key))
{
newDir.Remove(key);
}
newDir[key] = value;
Redis.Set<Dictionary<string, object>>(sessionId, newDir);
return true;
}
else
{
Dictionary<string, object> dic = new Dictionary<string, object>();
dic.Add(key, value);
Redis.Set<Dictionary<string, object>>(sessionId, dic);
return true;
}
}      //删除Session
public static bool DeleteSession(this RedisClient Redis, string key)
{
var requestCookie = HttpContext.Current.Request.Cookies["SessionId"];
string sessionId;
if (requestCookie == null)
{
return false;
}
sessionId = requestCookie.Value;
Redis.Expire(sessionId, 20 * 60);
Dictionary<string, object> dic = Redis.Get<Dictionary<string, object>>(sessionId);
if (dic == null)
{
return false;
}
if (dic.ContainsKey(key))
{
dic.Remove(key);
Redis.Set<Dictionary<string, object>>(sessionId, dic);
}
return true;
}       //获取Session
public static object GetSession(this RedisClient Redis, string key)
{
var requestCookie = HttpContext.Current.Request.Cookies["SessionId"];
string sessionId;
if (requestCookie == null)
{
return null;
}
sessionId = requestCookie.Value;
Dictionary<string, object> dic = Redis.Get<Dictionary<string, object>>(sessionId);
if (dic == null)
{
return null;
}
if (dic.ContainsKey(key))
{
Redis.Expire(sessionId, 20 * 60);
return dic[key];
}
return null;
}
}
}

    优点:  

        1.解决了session的性能问题;

        2.解决了应用程序的可扩展性;

        3.内存之间的共享;

        4.Session丢失的问题;

          

    这是自己对Redis的一个扩展Session,不知道是否算优,欢迎大牛拍砖纠正;

扩展Session机制的更多相关文章

  1. zookeeper源码分析之六session机制

    zookeeper中session意味着一个物理连接,客户端连接服务器成功之后,会发送一个连接型请求,此时就会有session 产生. session由sessionTracker产生的,sessio ...

  2. 理解Cookie和Session机制(转)

    目录[-] Cookie机制 什么是Cookie 记录用户访问次数 Cookie的不可跨域名性 Unicode编码:保存中文 BASE64编码:保存二进制图片 设置Cookie的所有属性 Cookie ...

  3. PHP中的SESSION机制

    [转] php中cookie和session是我们常用的两个变量了,一个是用户客户端的,一个用在服务器的但他们的区别与工作原理怎么样,下面我们一起来看看cookie和session机制原理吧.   c ...

  4. session机制详解以及session的相关应用

    session是web开发里一个重要的概念,在大多数web应用里session都是被当做现成的东西,拿来就直接用,但是一些复杂的web应用里能拿来用的session已经满足不了实际的需求,当碰到这样的 ...

  5. Cookie/Session机制

    这些都是基础知识,不过有必要做深入了解.先简单介绍一下. 二者的定义: 当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择, 都纪 ...

  6. 转:理解Cookie和Session机制

    原文: 理解Cookie和Session机制 摘要: Cookie工作原理 由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份.怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论 ...

  7. php中session机制的详解

    [补充]session_start()要放在php最前面,header()函数也要放在session_start()之后. [读了下面的文章转载的文章后自己的理解]: 1,通过phpinfo()函数可 ...

  8. Session机制详解

    转自:http://justsee.iteye.com/blog/1570652 虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能 ...

  9. 理解Cookie和Session机制

    转载: 理解Cookie和Session机制 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录 ...

随机推荐

  1. HDOJ 3037 Saving Beans

    如果您有n+1树,文章n+1埋不足一棵树m种子,法国隔C[n+m][m] 大量的组合,以取mod使用Lucas定理: Lucas(n,m,p) = C[n%p][m%p] × Lucas(n/p,m/ ...

  2. ZOJ 1649:Rescue(BFS)

    Rescue Time Limit: 2 Seconds      Memory Limit: 65536 KB Angel was caught by the MOLIGPY! He was put ...

  3. MVC基本概念和流程

    MVC基本概念和流程 MVC的概念 Model(模型):包含数据和行为.不过现在一般都分离开来:Value Object(数据) 和 服务层(行为). View(视图):负责进行模型的展示,一般就是展 ...

  4. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(2)-数据库访问层的设计Demo

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(2)-数据库访问层的设计Demo ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1)框架搭建 前言:这 ...

  5. html浏览器兼容性 JavaScript语法

    1.      在FireFox中能够使用与HTML节点对象ID属性值同样的JS变量名称,可是IE中不行. 解决的方法:在命名上区分HTML节点对象ID属性值和JS变量 2.      IE不支持JS ...

  6. JS function立即调用的几种写法

    //立即执行 (function () { alert(1) })() //立即执行 !function () { alert(1) }() //立即执行 +function () { alert(1 ...

  7. 数学思想方法-分布式计算-linux/unix技术基础(3)

    夹: ~表示当前用户的主文件夹 .它代表了当前文件夹 ..它代表的父文件夹 链接文件 使用不同的文件名指的是相同的数据或程序.硬链接 在相同的物理文件系统,创建一个硬链接 -bash-4.2$ fin ...

  8. Tair LDB基于Prefixkey中期范围内查找性能优化项目总结

    "Tair LDB基于Prefixkey该范围内查找性能优化"该项目是仅一个月.这个月主要是熟悉项目..以下从几个方面总结下个人在该项目上所做的工作及自己的个人所得所感. 项目工作 ...

  9. c++双缓冲技术,以避免闪烁绘图

    当数据量非常大时,画图可能须要几秒钟甚至更长的时间,并且有时还会出现闪烁现象,为了解决这些问题.可採用双缓冲技术来画图. 双缓冲即在内存中创建一个与屏幕画图区域一致的对象,先将图形绘制到内存中的这个对 ...

  10. 【设计模式】Abstract Factory模式

    抽象工厂模式是工厂方法模式的进一步强化.当工厂函数仅仅须要产生一种类型的产品(全部产品都继承自同一抽象基类)时,使用工厂方法模式就可以. 可是.当用户程序须要创建多种类型的产品,而这些产品又有一定的内 ...