分布式缓存扩展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. SSIS从理论到实战,再到应用(3)----SSIS包的变量,约束,常用容器

    原文:SSIS从理论到实战,再到应用(3)----SSIS包的变量,约束,常用容器 上期回顾: SSIS从理论到实战,再到应用(2)----SSIS包的控制流   首先我们来看看包里面的变量 SSIS ...

  2. Leetcode:convert_sorted_array_to_binary_search_tree

    一.     称号 排序后的数组成二叉搜索树. 二.     分析 BST的中序遍历是一个sorted-array,再构造回去成一个BST,先将中间的元素作为根节点,这个节点的左右各自是左子树和右子树 ...

  3. oracle_删除同一列的重复数据

    <!--删除同一列的重复数据 rowid 在orcle中 数据的物理地址---> delete from tbl_over_picture_alarm a where rowid not ...

  4. 【Linux】Vim编辑器-批量注释与反注释

    [-] vim编辑器---批量注释与反注释 方法一 块选择模式 插入注释 取消注释 方法二 替换命令 批量注释 取消注释 实例演示   vim编辑器---批量注释与反注释 在使用vim编写代码的时候, ...

  5. 线程同步synchronized

    一Java规划共享多个线程之间数据的能力. 当线程以异步方式訪问共享数据时.有时候是不安全的或者不和逻辑的. 比方卖火车票.同一时刻一个线程在读取数据,另外一个线程在处理数据,当处理数据的线程没有等到 ...

  6. Jquery--仿制360右下角弹出窗口

    原文:Jquery--仿制360右下角弹出窗口 先发浏览器效果图,给大家看. 要实现这样的效果,按照思路,第一步,写好CSS布局,将图片放到浏览器右下角的位置 CSS代码很灵活,我写的只是简单的一种而 ...

  7. 用fcntl()设置堵塞函数的堵塞性质

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types. ...

  8. sql事务,在sql2000里判断执行是否成功用@@ERROR 判断

    原文:sql事务,在sql2000里判断执行是否成功用@@ERROR 判断 贴个sql事务,在sql2000里判断执行是否成功用@@ERROR 判断 这个东西多少还是有点问题,sql2005了可以用t ...

  9. 浅谈 js 正则之 test 方法

    原文:浅谈 js 正则之 test 方法 其实我很少用这个,所以之前一直没注意这个问题,自从落叶那厮写了个变态的测试我才去看了下这东西.先来看个东西吧. var re = /\d/; console. ...

  10. hibernate 一对多关联关系(具体分析)

    在领域模型中, 类与类之间最普遍的关系就是关联关系. 在 UML 中, 关联是有方向的.  以 Customer 和 Order 为例: 一个用户能发出多个订单, 而一个订单仅仅能属于一个客户. 从 ...