扩展Session机制
分布式缓存扩展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机制的更多相关文章
- zookeeper源码分析之六session机制
zookeeper中session意味着一个物理连接,客户端连接服务器成功之后,会发送一个连接型请求,此时就会有session 产生. session由sessionTracker产生的,sessio ...
- 理解Cookie和Session机制(转)
目录[-] Cookie机制 什么是Cookie 记录用户访问次数 Cookie的不可跨域名性 Unicode编码:保存中文 BASE64编码:保存二进制图片 设置Cookie的所有属性 Cookie ...
- PHP中的SESSION机制
[转] php中cookie和session是我们常用的两个变量了,一个是用户客户端的,一个用在服务器的但他们的区别与工作原理怎么样,下面我们一起来看看cookie和session机制原理吧. c ...
- session机制详解以及session的相关应用
session是web开发里一个重要的概念,在大多数web应用里session都是被当做现成的东西,拿来就直接用,但是一些复杂的web应用里能拿来用的session已经满足不了实际的需求,当碰到这样的 ...
- Cookie/Session机制
这些都是基础知识,不过有必要做深入了解.先简单介绍一下. 二者的定义: 当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择, 都纪 ...
- 转:理解Cookie和Session机制
原文: 理解Cookie和Session机制 摘要: Cookie工作原理 由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份.怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论 ...
- php中session机制的详解
[补充]session_start()要放在php最前面,header()函数也要放在session_start()之后. [读了下面的文章转载的文章后自己的理解]: 1,通过phpinfo()函数可 ...
- Session机制详解
转自:http://justsee.iteye.com/blog/1570652 虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能 ...
- 理解Cookie和Session机制
转载: 理解Cookie和Session机制 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录 ...
随机推荐
- java安全编程
java安全程序实际上是一个点稍微防御性编程意味着内,竟java作为编程语言,较C,c++,本身被认为是比较安全的,随着C,C++这样的偏底层的编程语言比,java少了显示的指针调用.少了程序上的内存 ...
- erlang R17新socket选项{active,N}
erlang R17带来了新的socket选项{active,N} .与{active,once}连同应用层提供的流量控制.为什么会这样选择,{active,once}不能够有效地抑制了很多socke ...
- SQL Prompt5 破解版+使用说明 [转]
SQL脚本越写越多,总是觉得编写效率太过于低下,这和打字速度无关.在我个人编写SQL脚本时,至少会把SQL的格式排列成易于阅读的,因为其他人会阅读到你的SQL,无论是在程序中或是脚本文件中,良好的排版 ...
- RegisterStartupScript和RegisterClientScriptBlock区别
RegisterStartupScript(key, script) RegisterClientScriptBlock(key, script) 这两个方法的作用都是从前台向后台写脚本,且都接受两个 ...
- jQuery UI的datepicker日期控件如何让他显示中文
首先是引入UI的JS文件和模板文件,如下: <link rel=”stylesheet” href=”./ui/themes/le-frog/jquery.ui.all.css”> < ...
- 豆瓣api之OAuth认证
豆瓣api通过OAuth允许第三方应用访问用户数据,所以OAuth认证就是我们整个project的基础了. OAuth认证听起来挺神秘,其实挺简单的. 现在的大型网站的开放平台的认证几乎都是采用OAu ...
- maven和libgdx
这一篇是关于maven和libgdx的.本来我准备用gradle(现已有gradle模板了),不过暂时有点小问题,而同时libgdx官方提供了maven支持,为了快速上手还是选用maven了. 博客已 ...
- UVA The Sultan's Successors
题目例如以下: The Sultan's Successors The Sultan of Nubia has no children, so she has decided that thecou ...
- (C语言)共用体union的使用方法举例
曾经在学校学习C语言的时候一直搞不懂那个共用体union有什么用的.工作之后才发现它的一些妙用,现举比例如以下: 1. 为了方便看懂代码. 比方说想写一个3 * 3的矩阵,能够这样写: [ 注:以下用 ...
- Linux C语言操作MySQL
原文:Linux C语言操作MySQL 1.MySQL数据库简介 MySQL是一个开源码的小型关系数据库管理系统,体积小,速度快,总体成本低,开源.MySQL有以下特性: (1) 使用C和C++编写, ...