Asp.net负载均衡之Session
在WEB场中,动态网页往往会因为几台主机做了负载而产生SESSION丢失的问题,网上也有很多的介绍,我这里只将我经历的过程给大家分享一下:
系统要运行在负载平衡的 Web 场环境中,而系统配置文件web.config中的Session状态却设置为InProc(即在本地存储会话状态),导至在用户访问量大 时,Session常经超时的情况。引起这个现象的原因主要是因为用户通过负载平衡IP来访问WEB应用系统,某段时候在某台服务器保存了Session 的会话状态,但在其它的WEB前端服务器中却没有保存Session的会话状态,而随着并发量的增大,负载平衡会当作路由随时访问空闲的服务器,结果空闲 的服务器并没有之前保存的Session会话状态。
解决办法:
1.当您在负载平衡的 Web 场环境中运行 ASP.NET Web 应用程序时,一定要使用 SqlServer 或 StateServer 会话状态模式,在项目中我们基于性能考虑并没有选择SqlServer模式来存储Session状态,而是选择一台SessionStateServer 服务器来用户的Session会话状态。我们要在系统配置文件web.config中设置如下:
<sessionState mode="StateServer" cookieless="false" timeout="240" stateConnectionString="tcpip=192.168.0.1:42424" stateNetworkTimeout="14400" />
这里的红字体的IP一定要是同域的一台机器,在这台机器上进行第二步的操作,同时将其注册表中HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Servi ces\aspnet_state\Parameter
s\AllowRemoteConnection的键值改为1,然后重启本机的ASP.NET State Service服务
还要添加一项
<machineKey validationKey="78AE3850338BFADCE59D8DDF58C9E4518E7510149C46142D7AAD7F1AD49D95D4" decryptionKey="5FC88DFC24EA123C" validation="SHA1"/>
如何生成machineKey?
按照MSDN的标准说法:“对密钥进行配置,以便将其用于对 Forms 身份验证 Cookie 数据和视图状态数据进行加密和解密,并将其用于对进程外会话状态标识进行验证。”也就是说Asp.Net的很多加密,都是依赖于machineKey里面的值,例如Forms 身份验证 Cookie、ViewState的加密。默认情况下,Asp.Net的配置是自己动态生成,如果单台服务器当然没问题,但是如果多台服务器负载均衡,machineKey还采用动态生成的方式,每台服务器上的machinekey值不一致,就导致加密出来的结果也不一致,不能共享验证和ViewState,所以对于多台服务器负载均衡的情况,一定要在每台站点配置相同的machineKey。
machineKey生成的算法:
validationKey = CreateKey(20);
decryptionKey = CreateKey(24);
protected string CreateKey(int len)
{
byte[] bytes = new byte[len];
new RNGCryptoServiceProvider().GetBytes(bytes);
StringBuilder sb = new StringBuilder();
for(int i = 0; i < bytes.Length; i++)
{
sb.Append(string.Format("{0:X2}",bytes[i]));
}
return sb.ToString();
}
附参考的matchineKey配置:
<?xml version="1.0"?>
<configuration>
<system.web>
<machineKey validationKey="3FF1E929BC0534950B0920A7B59FA698BD02DFE8" decryptionKey="280450BB36319B474C996B506A95AEDF9B51211B1D2B7A77" decryption="3DES" validation="SHA1"/>
</system.web>
</configuration>
2. 我们同时还要在SessionStateServer 服务器中启动ASP.NET State Service服务,具体设置:控制面板>>管理工具>>服务>>ASP.NET State Service,把它设为自动启动即可。
3. 每台前端WEB服务的Microsoft“Internet 信息服务”(IIS)设置
要在 Web 场中的不同 Web 服务器间维护会话状态,Microsoft“Internet 信息服务”(IIS) 配置数据库中 Web 站点的应用程序路径(例如,\LM\W3SVC\2)与 Web 场中所有 Web 服务器必须相同。大小写也必须相同,因为应用程序路径是区分大小写的。在一台 Web 服务器上,承载 ASP.NET 应用程序的 Web 站点的实例 ID 可能是 2(其中应用程序路径是 \LM\W3SVC\2)。在另一台 Web 服务器上,Web 站点的实例 ID 可能是 3(其中应用程序路径是 \LM\W3SVC\3)。因此,Web 场中的 Web 服务器之间的应用程序路径是不同的。我们必须使Web 场Web 站点的实例 ID 相同即可。你可以在IIS中把某一个WEB配置信息保存为一个文件,其他Web 服务器的IIS配置可以来自这一个文件。您如果想知道具体的设置请访问Microsoft Support网站:http://support.microsoft.com/default.aspx?scid=kb;zh-cn;325056
补充一些相关资料:
PRB: Session Variables Are Lost If You Use FRAMESET in Internet Explorer 6.0
http://support.microsoft.com/kb/323752/EN-US/#
PRB: Session Data Is Lost When You Use ASP.NET InProc Session State Mode
http://support.microsoft.com/?id=324772
PRB:如果您使用 SqlServer 或 StateServer 会话模式 Web 场中会丢失会话状态
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;325056
ASP.NET Session State FAQ
http://www.eggheadcafe.com/articles/20021016.asp
参考来自:http://hi.baidu.com/panshuaiyang
应用程序如何用两种方式存储Session信息
以下的各种操作主要是针对这一段配置展开。让我们先看看这一段配置中所包含的内容的意思。sessionState节点的语法是这样的:
<sessionState mode="Off|InProc|StateServer|SQLServer"
cookieless="true|false"
timeout="number of minutes"
stateConnectionString="tcpip=server:port"
sqlConnectionString="sql connection string"
stateNetworkTimeout="number of seconds"
/>
必须有的属性是
属性 选项 描述
mode 设置将Session信息存储到哪里
Off 设置为不使用Session功能
InProc 设置为将Session存储在进程内,就是ASP中的存储方式,这是默认值。
StateServer 设置为将Session存储在独立的状态服务中。
SQLServer 设置将Session存储在SQL Server中。
可选的属性是:
属性 选项 描述
cookieless 设置客户端的Session信息存储到哪里
ture 使用Cookieless模式
false 使用Cookie模式,这是默认值。
timeout 设置经过多少分钟后服务器自动放弃Session信息。默认为20分钟
stateConnectionString 设置将Session信息存储在状态服务中时使用的服务器名称和端口号,例如:"tcpip=127.0.0.1:42424”。当mode的值是StateServer是,这个属性是必需的。
sqlConnectionString 设置与SQL Server连接时的连接字符串。例如"data source=localhost;Integrated Security=SSPI;Initial Catalog=northwind"。当mode的值是SQLServer时,这个属性是必需的。
stateNetworkTimeout 设置当使用StateServer模式存储Session状态时,经过多少秒空闲后,断开Web服务器与存储状态信息的服务器的TCP/IP连接的。默认值是10秒钟。
ASP.NET中客户端Session状态的存储
在我们上面的Session模型简介中,大家可以发现Session状态应该存储在两个地方,分别是客户端和服务器端。客户端只负责保存相应网站的 SessionID,而其他的Session信息则保存在服务器端。在ASP中,客户端的SessionID实际是以Cookie的形式存储的。如果用户 在浏览器的设置中选择了禁用Cookie,那末他也就无法享受Session的便利之处了,甚至造成不能访问某些网站。为了解决以上问题,在ASP.NET中客户端的Session信息存储方式分为:Cookie和Cookieless两种。
ASP.NET中,默认状态下,在客户端还是使用Cookie存储Session信息的。如果我们想在客户端使用Cookieless的方式存储Session信息的方法如下:
找到当前Web应用程序的根目录,打开Web.Config文件,找到如下段落:
<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
cookieless="false"
timeout="20"
/>
这段话中的cookieless="false"改为:cookieless="true",这样,客户端的Session信息就不再使用 Cookie存储了,而是将其通过URL存储。关闭当前的IE,打开一个新IE,重新访问刚才的Web应用程序,就会看到类似下面的样子:
其中,http://localhost/MyTestApplication/(ulqsek45heu3ic2a5zgdl245) /default.aspx中黑体标出的就是客户端的Session ID。注意,这段信息是由IIS自动加上的,不会影响以前正常的连接。
ASP.NET中服务器端Session状态的存储
准备工作
为了您能更好的体验到实验现象,您可以建立一个叫做SessionState.aspx的页面,然后把以下这些代码添加到<body></body>中。
<scriptrunat="server">
Sub Session_Add(sender As Object, e As EventArgs)
Session("MySession") = text1.Value
span1.InnerHtml = "Session data updated! <P>Your session contains: <font color=red>" & \
Session("MySession").ToString() & "</font>"
End Sub
Sub CheckSession(sender As Object, eAs EventArgs)
If (Session("MySession")Is Nothing) Then
span1.InnerHtml = "NOTHING, SESSION DATA LOST!"
Else
span1.InnerHtml = "Your session contains: <font color=red>" & \
Session("MySession").ToString() & "</font>"
End If
End Sub
</script>
<formrunat="server"id="Form2">
<inputid="text1"type="text"runat="server"name="text1">
<inputtype="submit"runat="server"OnServerClick="Session_Add"
value="Add to Session State" id="Submit1"name="Submit1">
<inputtype="submit"runat="server"OnServerClick="CheckSession"
value="View Session State" id="Submit2"name="Submit2">
</form>
<hrsize="1">
<fontsize="6"><spanid="span1"runat="server" /></font>
这个SessionState.aspx的页面可以用来测试在当前的服务器上是否丢失了Session信息。
将服务器Session信息存储在进程中
让我们来回到Web.config文件的刚才那段段落中:
<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
cookieless="false"
timeout="20"
/>
当mode的值是InProc时,说明服务器正在使用这种模式。
这种方式和以前ASP中的模式一样,就是服务器将Session信息存储在IIS进程中。当IIS关闭、重起后,这些信息都会丢失。但是这种模式也有 自己最大好处,就是性能最高。应为所有的Session信息都存储在了IIS的进程中,所以IIS能够很快的访问到这些信息,这种模式的性能比进程外存储 Session信息或是在SQL Server中存储Session信息都要快上很多。这种模式也是ASP.NET的默认方式。
好了,现在让我们做个试验。打开刚才的SessionState.aspx页面,随便输入一些字符,使其存储在 Session中。然后,让我们让IIS重起。注意,并不是使当前的站点停止再开始,而是在IIS中本机的机器名的节点上点击鼠标右键,选择重新启动 IIS。(想当初使用NT4时,重新启动IIS必须要重新启动计算机才行,微软真是@#$%^&)返回到SessionState.aspx页面中,检查刚才的Session信息,发现信息已经丢失了。
将服务器Session信息存储在进程外
首先,让我们来打开管理工具->服务,找到名为:ASP.NET State Service的服务,启动它。实际上,这个服务就是启动一个要保存Session信息的进程。启动这个服务后,你可以从Windows任务管理器 ->进程中看到一个名为aspnet_state.exe的进程,这个就是我们保存Session信息的进程。
然后,回到Web.config文件中上述的段落中,将mode的值改为StateServer。保存文件后的重新打开一个IE,打开 SessionState.aspx页面,保存一些信息到Session中。这时,让我们重起IIS,再回到SessionState.aspx页面中查 看刚才的Session信息,发现没有丢失。
实际上,这种将Session信息存储在进程外的方式不光指可以将信息存储在本机的进程外,还可以将Session信息存储在其他的服务器的进程中。 这时,不光需要将mode的值改为StateServer,还需要在stateConnectionString中配置相应的参数。例如你的计算你是 192.168.0.1,你想把Session存储在IP为192.168.0.2的计算机的进程中,就需要设置成这 样:stateConnectionString="tcpip=192.168.0.2:42424"。当然,不要忘记在192.168.0.2的计算 机中装上.NET Framework,并且启动ASP.NET State Services服务。
将服务器Session信息存储在SQL Server中
首先,还是让我们来做一些准备工作。启动SQL Server和SQL Server代理服务。在SQL Server中执行一个叫做InstallSqlState.sql的脚本文件。这个脚本文件将在SQL Server中创建一个用来专门存储Session信息的数据库,及一个维护Session信息数据库的SQL Server代理作业。我们可以在以下路径中找到那个文件:
[system drive]\winnt\Microsoft.NET\Framework\[version]\
然后打开查询分析器,连接到SQL Server服务器,打开刚才的那个文件并且执行。稍等片刻,数据库及作业就建立好了。这时,你可以打开企业管 理器,看到新增了一个叫ASPState的数据库。但是这个数据库中只是些存储过程,没有用户表。实际上Session信息是存储在了tempdb数据库 的ASPStateTempSessions表中的,另外一个ASPStateTempApplications表存储了ASP中Application 对象信息。这两个表也是刚才的那个脚本建立的。另外查看管理->SQL Server代理->作业,发现也多了一个叫做ASPState_Job_DeleteExpiredSessions的作业,这个作业实际上就是 每分钟去ASPStateTempSessions表中删除过期的Session信息的。
接着,我们返回到Web.config文件,修改mode的值改为SQLServer。注意,还要同时修改sqlConnectionString的值,格式为:
sqlConnectionString="data source=localhost; Integrated Security=SSPI;"
其中data source是指SQL Server服务器的IP地址,如果SQL Server与IIS是一台机子,写127.0.0.1就行了。Integrated Security=SSPI的意思是使用Windows集成身份验证,这样,访问数据库将以ASP.NET的身份进行,通过如此配置,能够获得比使用 userid=sa;password=口令的SQL Server验证方式更好的安全性。当然,如果SQL Server运行于另一台计算机上,你可能会需要通过Active Directory域的方式来维护两边验证的一致性。
同样,让我们做个试验。向SessionState.aspx中添加Session信息,这时发现Session信息已经存在SQL Server中了,即使你重起计算机,刚才的Session信息也不会丢失。现在,你已经完全看见了Session信息到底是什么样子的了,而且又是存储 在SQL Server中的
Asp.net负载均衡之Session的更多相关文章
- asp.net 负载均衡下session存储的解决方法
转自:http://www.cnblogs.com/david100zhang/archive/2011/12/28/2304917.html 在WEB场中,动态网页往往会因为几台主机做了负载而产生S ...
- ASP.NET 负载均衡 StateServer Session共享问题(经验记录)
(源地址:http://www.cnblogs.com/ryhan/p/3748976.html) 最近在改造公司的一个系统 支持F5硬件负载,由于系统后面还跟了个异步工具,需要将Admin上传的文件 ...
- windows使用nginx+memcached实现负载均衡和session或者缓存共享
windows使用nginx+memcached实现负载均衡和session或者缓存共享 两台server server1:115.29.186.215 windows2008 64位操作系统 ser ...
- 通过Nginx+tomcat+redis实现反向代理 、负载均衡及session同步
一直对于负载均衡比较陌生,今天尝试着去了解了一下,并做了一个小的实验,对于这个概念有一些认识,在此做一个简单的总结 什么是负载均衡 负载均衡,英文 名称为Load Balance,指由多台服务器以对称 ...
- nginx+tomcat+redis负载均衡及session共享
概述 本文档是用来详细描述 nginx+tomcat+redis负载均衡实现session共享 所需软件及下载地址 软件名称 下载地址 功能说明 Nginx-v1.6.0 http://nginx.o ...
- Apache+Tomcat +mod_proxy集群负载均衡及session
序言: 在玩Apache+Tomcat +mod_jk集群负载均衡及session的时候发现,还有一种方式可以实现,就是网上各位大牛们说的mod_proxy反向代理. 实在弄的我的知识细胞洋洋.实 ...
- Weblogic 12c 负载均衡和session复制
在上一篇,我们介绍了weblogic集群的部署和session的复制,如何将请求负载均衡到这个三个服务器上呢? 这里提供两种方式:(1)weblogic自带的proxy代理 (2) ng ...
- nginx+tomcat负载均衡和session复制
本文介绍下传统的tomcat负载均衡和session复制. session复制是基于JVM内存的,当然在当今的互联网大数据时代,有更好的替代方案,如将session数据保存在Redis中. 1.安装n ...
- 玩转spring boot——负载均衡与session共享
前言 当项目上线后,如果要修复bug或扩充功能,都需要重启tomcat服务.此时,正在使用应用的用户们就需要等待服务器的重启,而这就会造成不好的用户体验.还有,当仅仅只有一台tomcat服务时,如果 ...
随机推荐
- android欢迎页
在进入程序后,会在一个页面停留几秒然后自动跳转到程序主界面,这个页面就是欢迎页. 首先新建个java文件,给他起名叫做WelcomeActivity 在里面我们通过一个匿名类new Handler,在 ...
- 开启vmotion,实现虚拟机可以在线迁移的选项
先决条件: 1.vcenter5.5 2.vmotion服务开启 3.分布式交换机已经部署完毕 4.虚拟机在线迁移必须在web管理下,在vclient不可以
- ANSI与Unicode的转换
最近遇到中文路径访问的问题,又重新学习了一遍ansi与Unicode的知识,博文记录下来以供后续参考. ANSI 编码 ANSI是一种字符代码,为使计算机支持更多语 言,通常使用0x80~0xFF 范 ...
- GitHub in vs2010、vs2013
GitHub在使用上大致和其他源代码管理工具一样,个人源代码管理和分享一大利器,而且vs2010和vs2013配置也没有任何区别,简单做了一下图文配置说明 一.注册github 1.github.co ...
- 大杀器TheFatRat
项目地址:https://github.com/Screetsec/TheFatRat 安装TheFatRat root@sch01ar:/sch01ar# git clone https://git ...
- Unable to correct problems, you have held broken package
其实这篇接着上文(一),主要是解决samba安装的问题,中间又是一路曲折.不过这个问题也算是比较典型,有必要记录一下. #apt-get install smb* 安装失败.其实顺利的话,直接一条这样 ...
- 基于Halcon的一维条码识别技巧
Bar Code 条形码 1.clear_all_bar_code_models 清除所有条形码模型释放内存clear_all_bar_code_models( : : : )2.clear_b ...
- DDD学习笔录——提炼问题域之与领域专家一起获得领域见解
业务和开发团队之间的协作是DDD必不可少的部分,并且它是处于开发阶段的产品获得成功的关键. 领域专家指的是那些从业务领域的政策和工作流程到棘手处和特性都具有深刻理解的人.能够为你的问题区域提供深刻见解 ...
- [原创]Spring boot 框架构建jsp web应用
说明 Spring boot支持将web项目打包成一个可执行的jar包,内嵌tomcat服务器,独立部署 为支持jsp,则必须将项目打包为war包 pom.xml中设置打包方式 <packagi ...
- 优于jdbc的mybatis框架入门
1.什么是mybatis? MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架. MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索. MyB ...