今天遇到了这个问题,于是研究了一下。要解决这个问题,首先就要明白一些Session的机理。Session在服务器是以散列表形式存在的,我们都知道Session是会话级的,每个用户访问都会生成一个Session。那么服务器是怎么区分不同用户的Session?又是怎么将不同用户的Session与不同的用户绑定的呢?下面我们来研究一下,以下纯属我个人的理解,如有错误请指证。

Session在服务器端是以散列表的形式存在的,区分每一个Session是通过SessionID来实现的,所以可以说这个SessionID是一个Key是一个全局唯一的值。我们可以通过ASP.NET来打印出SessionID,如下代码:

protected void Page_Load(object sender, EventArgs e)
        {
            Response.Write(Session.SessionID.ToString());
        }

这样我们就得到了这样的值:0julmoedn0kz3gyfnr1vksv0,
有点像是GUID,就算不是算法也都是类似的,主要就是为了保证全局唯一性。这样就达到了区分不同用户的Session的目的。接下来还有第二个问题,那
就是SessionID有了,但是它又是怎么和相应的访问者(用户)绑定的呢?比如说用户A访问维护了自己的SessionID,用户B访问也维护了自己
的SessionID。我们都知道web是基于http无链接的,他们又是怎么做到的呢?没错,答案就是在客户端存储了自己的SessionID。浏览器
存储SessionID有两种方式,一种就是利用Cookies;还有一种就是利用url参数(这种我们不常用,很不友好)。

话题说到Cookies上来了,怎么的?没想到
Session和Cookies还有这样的关系吧?(很多人知道,别BS我)没错,当我们请求一个URL时候,服务器会生成一个全局的
SessionID,并且把这个值以Cookies的形式保存在客户端也就是浏览器(这里暂不讨论url方式)。这样当用户再去请求的时候,在http头
把这个SessionID的Cookie发到服务器端,服务器就去找这个SessionID,如果找到了。就证明这个用户的状态是存在的。

知道了这个原理,我们的问题也就有眉头了,即然是用Cookies来保存SessionID,那么我们就可以在Cooikes上做手脚了。我们都知道Cooikes记录方式是以域(例如:http://www.local.com/)为区分的,这也是各种浏览器规定的。如果不这么做,安全性就会有问题。我们要做的就是让指定Cookies的父域方式,不指定具体指域,这样Cookies就可以跨子域了。Cookies可以像这样指定域:

 protected void Page_Load(object sender, EventArgs e)
        {
            Response.Cookies["MyCook"].Domain = ".local.com";
        }

这样,我们所有的二级域全部是认这一个主域的,比如
a.local.com;b.local.com;user.local.com等等。有了这个认识,我想大家心里也有数了,该怎么怎么做,但是现在问题
是用来生成SessionID的方法是ASP.NET自动实现的,我们又怎么去干涉它呢?这是这样做的,不主动干涉它,但是我可以操作它的Cookies
啊。接下来我们就研究ASP.NET存SessionID的Cooike的名字是什么。经过网上很容易就查找到了,名字
是:ASP.NET_SessionId,这个就是SessionId的Cookies名字。我们可以在Session_Start中这样写:


 protected void Session_Start(object sender, EventArgs e)
        {
            Response.Cookies["ASP.NET_SessionId"].Value = Session.SessionID.ToString();
            Response.Cookies["ASP.NET_SessionId"].Domain = ".local.com";
        }

代码的意思是每次会话开始的时候,我都把ASP.NET_SessionId这个
Cookie重写成我们已有的SessionID,并且把这个Cookie的domain指定为父域,比如:.local.com,这样就可以实现跨子域
的Session共享了。怎么样很简单吧?

我们还有一个外题问题,就是客户端保存的问题解决了,但是服务器端的Session怎么办?
一般情况下我们不同的子域做的是指向不同的服务器的,比如user.local.com
专门一台服务器,yellow.local.com专门一台服务器。这时它们别说是进程了,连物理上都不是一个了。Session怎么共享?这时就用到另
一个方法了,我们默认的Session是存储在asp.net进程中的,这样没法互相访问,如下面所示:

 <sessionState mode="InProc" />

我们可以修改为State Server方式,这是一个单独的服务可以用来存储ASP.NET Session的,它支持分布式远程主机的,这样我们可以用一台服务器来提供Session服务,如下所示:

 <sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="30" />

这样,就完全实现了不同子域的Session共享了。

前面说到Url保存SessionId的方式,由于不常用,给大家演示一下,如下配置就可以了:

    <sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="30" cookieless="true" />

cookieless属性指定是否用cookie来保存SessionId,我们运行一下得到下面的样子:

http://localhost:3380/(S(dqxcs455n4u2vg55ia51fvqg))/default.aspx

Asp.Net集群中Session共享的更多相关文章

  1. 集群中Session共享解决方案分析

    一.为什么要Session共享 Session存储在服务器的内存中,比如Java中,Session存放在JVM的中,Session也可以持久化到file,MySQL,redis等,SessionID存 ...

  2. 关于 tomcat 集群中 session 共享的三种方法

    前两种均需要使用 memcached 或redis 存储 session ,最后一种使用 terracotta 服务器共享. 建议使用 redis,不仅仅因为它可以将缓存的内容持久化,还因为它支持的单 ...

  3. spring session实现集群中session共享

    本文转自:http://dorole.com/1422/ 使用框架的会话管理工具,也就是本文要说的spring-session,可以理解是替换了Servlet那一套会话管理,既不依赖容器,又不需要改动 ...

  4. PHP 分布式集群中session共享问题以及session有效期的设置

    https://blog.csdn.net/m_nanle_xiaobudiu/article/details/81177698

  5. 通过memcached来实现对tomcat集群中Session的共享策略

    近期在做一套集群的实现,实现的方案是在Linux下完成对Apache + Tomcat 负载均衡的功能. 上述功能已经实现,有需要了解的朋友可以看我另外一篇博文. Linux下Apache与Tomca ...

  6. Redis+Tomcat+Nginx集群实现Session共享,Tomcat Session共享

    Redis+Tomcat+Nginx集群实现Session共享,Tomcat Session共享 ============================= 蕃薯耀 2017年11月27日 http: ...

  7. 集群间Session共享问题解决方案

    两个基本概念的生命周期 session: 当新客户端发现一个HTTP请求时服务端会创建一个session.并分配一个sessionID作为服务端来客户端的识别,session对象会保存在服务端.此时s ...

  8. Java集群之session共享解决方案

    随着互联网的日益壮大,网站的pv和uv成线性或者指数倍的增加.单服务器单数据库早已经不能满足实际需求.比如像盛大,淘宝这样的大型网络公司,更是如此.     集群,也就是让一组计算机服务器协同工作,达 ...

  9. tomcat集群及session共享

    一般来说,java web app主要用作两个领域: 1.api.api一般是无状态的,所以无需考虑session共享的问题 2.传统web应用和网站,如crm,oa,erp,b2c,bbs等.尤其b ...

随机推荐

  1. 图片处理中的Dithering技术

    话说二战的时候,美国轰炸机每次执行任务,除了满载着威力强大的炸弹以外,还常常要装配一台计算机,飞机飞行方向和投弹的抛物线的计算都离不开这台机器.可是世界上第一台电子计算机在二战结束后才发明,轰炸机上当 ...

  2. jq的合成事件

    jq中有两个合成事件 hover()和toggle() 1.hover() hover方法用于模拟光标悬停事件.当光标移动到元素上时,会触发指定的第一个函数(enter),当光标移出这个元素时,会触发 ...

  3. jquery 延迟执行实例介绍

    代码如下: $(function(){ var $inputs = $('input[type=button]') .delay(500) .queue(function(){$(this).hide ...

  4. JSP标准标签库(JSTL)--JSTL简介与安装

    对于MVC设计模式来讲,我们一直强调,在一个JSP钟scriptlet代码越少越好,但是只靠以前的概念很难实现,因为标签的开发特别麻烦,所以为了简化标签,也为了让标签更具备一些通用性,所以一般在开发中 ...

  5. zf-关于改绍兴县2个简单的BUG却需要ORACLE数据库的感慨

    装了一天你的数据库,其实可以直接检出拿到后台代码,然后远程实施让他进项目,我在他的项目上找action,找图片都是一样的,有时候需求文档上也是会截图到action的,蛋疼,这么简单的方法我居然忘记了.

  6. zf-关于更改账号密码的问题

    一般项目的数据库里都会有一个 SYS_USER表 里面有账号密码 一般 202……70 的都是123加密后的字符串 如果碰到项目运行之后不知道登陆密码的时候 可以在数据库中 把USER_PASS 改成 ...

  7. FusionChart实现柱状图、饼状图的动态数据显示 附Demo

    最近做的项目中需要用饼状图显示——'问卷调查'的统计结果(之前用过FusionChart做过柱状图的数据展示,那还是两年前的事了),在网上查了下FusionChart实现饼状图显示方面的资料,却发现资 ...

  8. 前端HR告诉你—如何面试Web前端开发

    分享一篇HR前端面试心得: 面试前端工程师对我来说是一件非常有意思的事,因为面试过程很大程度上也是自我提升的过程.无论大公司还是小公司,之所以在如何招聘到真正有能力的,前端工程师方面会遇到同样的问题. ...

  9. 关于NIOS ii烧写的几种方式

    1. 方法一:.sof和.elf全部保存在FPGA内,程序加载和运行也是在FPGA内部. 把FPGA的配置文件.sof通过JTAG方式下载(其实是在线运行)进入FPGA本身,此时在NIOS II的界面 ...

  10. 左倾堆(C#)

    参考:http://www.cnblogs.com/skywang12345/p/3638384.html using System; using System.Collections.Generic ...