关于搭建Session服务器(转载)
Session服务器配置指南与使用经验
一.摘要
所有Web程序都会使用Session保存数据. 使用独立的Session服务器可以解决负载均衡场景中的Session共享问题.本文介绍.NET平台下建立Session服务器的几种办法, 并介绍在使用Session时的各种经验和技巧.
二.关于Session,SessionID和Cookies
Session数据保存在服务器端, 但是每一个客户端都需要保存一个SessionID, SessionID保存在Cookies中, 关闭浏览器时过期.
在向服务器发送的HTTP请求中会包含SessionID, 服务器端根据SessionID获取获取此用户的Session信息.
很多初级开发人员不知道SessionID和Cookies的关系, 所以常常认为两者没有联系. 这是不正确的. 正是因为SessionID保存在Cookies中, 所以在我们保存Cookies的时候,一定要注意不要因为Cookies的大小和个数问题而导致SessionID对象. 在我们的程序中, 对SessionID的Cookies有特殊的处理:
/// <summary> /// 写入cookie.
/// </summary> /// <param name="day"></param>
/// <returns></returns> public bool SetCookie(int day)
{
string CookieName = GetType().ToString(); HttpCookie SessionCookie = null;
//对 SessionId 进行备份. if (HttpContext.Current.Request.Cookies["ASP.NET_SessionId"] != null)
{
string SesssionId = HttpContext.Current.Request.Cookies["ASP.NET_SessionId"].Value.ToString();
SessionCookie = new HttpCookie("ASP.NET_SessionId");
SessionCookie.Value = SesssionId;
}
//省略掉中间的代码部分.只保留备份SessionID和找回SessionID的逻辑
//如果cookie总数超过20 个, 重写ASP.NET_SessionId, 以防Session 丢失. if (HttpContext.Current.Request.Cookies.Count > 20 && SessionCookie != null) { if (SessionCookie.Value != string.Empty) { HttpContext.Current.Response.Cookies.Remove("ASP.NET_SessionId"); HttpContext.Current.Response.Cookies.Add(SessionCookie); } } return true; }
三.搭建Session服务器的几种方式
将Session保存在独立的服务器中可以实现在多台Web服务器之间共享Session.虽然我们也可以自己开发Session存储系统, 但是使用ASP.NET自带的存储机制将更加便捷.
.NET提供了5种保存Seission的方式:
方式名称
存储方式 性能
Off
设置为不使用Session功能
无
InProc
设置为将Session存储在进程内,就是ASP中的存储方式,这是默认值。
性能最高
StateServer
设置为将Session存储在独立的状态服务中。通常是aspnet_state.exe进程.
性能损失10-15%
SQLServer
设置将Session存储在SQL Server中。
性能损失10-20%
Customer
自定制的存储方案
由实现方式确定
我们可以在Web.Config中配置程序使用的Session存储方式.默认情况下是InProc, 即保存在IIS进程中. 关于Off, InProc和Customer本文不做讲解. 相关文章大家都可以在网上搜索到.
下面主要讲解 StateServer 和 SQLServer 的应用.
四.使用 StateServer 模式搭建Session服务器
(1)服务器端配置
1.启动 Asp.net State service服务.(这个服务默认的状态为手动.修改为自动并启动.)
2.修改注册表: [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\aspnet_state\Parameters]
设置 AllowRemoteConnection = 1 , 设置 Port = 42424 (十进制,默认即为42424)
Port是服务的端口号
AllowRemoteConnection 表示是否允许其他机器连接,0为仅能本机使用,1为可以供其他机器使用.
(2)客户端设置
在Web应用程序的Web.Config中, 我们需要修改 <configuration> / <system.web> 的<sessionState>节点.如果没有
没有则添加(默认使用的是InProc方式)
<sessionState mode="StateServer" stateConnectionString="tcpip=服务器ip:42424" cookieless="false" timeout="60"/>
上面的参数我们可以根据需要修改.
五.使用SqlServer模式搭建Session服务器
(1)服务器端配置
使用SqlServer模式搭建Session服务器端有两种方式. ASP.NET 1.0和1.1版本请使用方式a, 2.0即以上版本请使用方式b.
a.使用SQL文件创建Session数据库
在ASP.NET 1.0和1.1 版本中, 只能使用这种方式.对于2.0及其以上版本,请使用aspnet_regsql.exe工具.(当然此方法也通用2.0版本)
.net提供了数据库安装脚本,可以在机器的windows文件夹中找到:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ InstallSqlState.sql
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ InstallSqlStateTemplate.sql
根据ASP.NET的版本不同, 需要使用不同的SQL脚本. ASP.NET主要有1.1和2.0两个版本,可以在不同的版本文件夹找到这两个SQL.
InstallSqlState.sql 是创建默认名称的数据库"[ASPState]".此SQL可以直接运行.
InstallSqlStateTemplate.sql 可以使用自己指定的数据库保存数据.此SQL需要自己修改后运行, 打开SQL文件将其中 [DatabaseNamePlaceHolder] 替换为自己指定的数据库名称.
执行installsqlstate.sql时不需要指定数据库,可以在任意数据库上执行.此SQL会自己创建新的数据库
b. 使用aspnet_regsql.exe工具
ASP.NET 2.0版本后微软提供了aspnet_regsql.exe工具可以方便的配置Session数据库.该工具位于 Web 服务器上的"系统根目录\Microsoft.NET\Framework\版本号"文件夹中.
使用举例:
aspnet_regsql.exe -S . -U sa -P 123456 -ssadd -sstype p
-S参数:
表示数据库实例名称. 可以用"."表示本机.
-U和-P参数:
表示用户名和密码.
-E参数:
可以再-U –P 与 -E中选择一组. –E表示以当前系统用户通过windows身份验证登录数据库, -U -P则是使用SqlServer用户登录数据库.
-ssadd / –ssremove 参数:
-ssadd表示是添加Session数据库, -ssremove表示移除Session数据库.
sstype 参数:
选项
说明
t
将会话数据存储到 SQL Server tempdb 数据库中。这是默认设置。如果将会话数据存储到 tempdb 数据库中,则在重新启动 SQL Server 时将丢失会话数据。
p
将会话数据存储到 ASPState 数据库中,而不是存储到 tempdb 数据库中。
c
将会话数据存储到自定义数据库中。如果指定 c 选项,则还必须使用 -d 选项包括自定义数据库的名称。
(2)Session客户端设置
此房是同样需要Web应用程序修改Web.Config中的<sessionState>节点.如果使用默认的数据库(ASPState库), 则配置如下:
<sessionState mode="SQLServer" sqlConnectionString="server=192.168.9.151; uid=sa; pwd=123456;" />
如果使用了自定义的数据库名称,则还需要制定allowCustomSqlDatabase属性并在数据库连接串中指定数据库:
<sessionState mode="SQLServer" allowCustomSqlDatabase="true" sqlConnectionString="server=192.168.9.151; DataBase=MyAspState;uid=sa; pwd=123456;" />
六.使用经验与技巧总结
下面是SessionID, Session_End时间, StatServer模式 和 SqlServer模式的各种经验和技巧总结.
(1)StateServer模式:
1.在web farm中,请确认在所有的web服务器上有相同的<machineKey>
2. 要保存在Session中的对象是可序列化的。
3.为了在web farm中的不同web服务器上维护session state,IIS Metabase中的网站应用程序路径(如\LM\W3SVC\2)应该在所有的服务器上保持一致(大小写敏感).
4. ASP.NET处理Session是在Machine.Config中配置的HttpModuel模块, 在.NET的安装目录下的Config文件夹中, 查看Web.Config(1.1版本是在Machine.Config):
<httpModules> ...
<add name="Session" type="System.Web.SessionState.SessionStateModule"/> ...
</httpModules>
确认此模块是否存在.
5.StateServer不支持负载均衡, 所以如果大并发推荐使用SqlServer模式, 可以享受到SqlServer的高性能和安全性.虽然存储效率会有下降.
6.需要让所有机器的MachineKey相同.在Machine.Config中配置:
<machineKey validationKey="1234567890123456789012345678901234567890AAAAAAAAAA" decryptionKey="123456789012345678901234567890123456789012345678" validation="SHA1" decryption="Auto" />
(2)SqlServer模式:
1. 要保存在Session中的对象是可序列化的。
2. 如果使用了默认是数据库, 则在客户端配置文件中的数据库链接字符串的用户,需要拥有ASPState和tempdb两个库的dbowner权限.
3. 在SQLServer模式下,session过期是由SQL Agent使用一个注册任务完成的,要确认SQL Agent已经运行。否则无法清理过期的Session数据, 会导致数据库数据一直增加.
4. 如果使用SqlServer模式时, 对于Web场中的各服务器的 ASP.NET 应用程序路径必须是相同的。请在 IIS 配置数据库中对 Web 场中的所有 Web 服务器进行 Web 站点的应用程序路径同步。大小写一定要相同,因为 Web 站点的应用程序路径是区分大小写的。
5.需要让所有机器的MachineKey相同.在Machine.Config中配置:
<machineKey validationKey="1234567890123456789012345678901234567890AAAAAAAAAA" decryptionKey="123456789012345678901234567890123456789012345678" validation="SHA1" decryption="Auto" />
(3)Session:
1. 不能直接通过Session服务器在ASP.NET和ASP之间共享Session. 请使用微软提供的解决方案:
http://msdn.microsoft.com/zh-cn/library/aa479313.aspx
2. 在不同的应用程序或一个网站的不同虚拟目录之间无法共享Session
3. Session的过期时间是滑动时间.
4. Session存储.NET自带的值类型性能最优. 存储对象会降低性能.
(4)SessionID:
1.SessionID 还可以保存在URL上, 设置Web.Config文件中的System.Web/sessionState节点的Cookiesless属性即可:
<sessionState cookieless="UseUri" />
2. 一般在Session超时或删除之后,SessionID保持不变. 因为Session过期后会在服务器端清除数据, 但是SessionID保存在用户浏览器上, 所以只要浏览器不关闭则HTTP头中的SessionID保持不变.
3.关闭浏览器后再访问, SessionID会不同.
4.每打开一个IE6窗口, SessionID都不同, 在IE6中两个窗口的Session不能共享.
5.FireFox的标签页和新的FireFox窗口, SessionID都相同, 在FF的窗口和标签页上Session能共享.
6.对于包含FrameSet的页面,比如:
<frameset cols="25%,50%,25%"> <frame src="SessionID.aspx"> <frame src="SessionID.aspx"> <frame src="SessionID.aspx"> </frameset>
如果后缀名是.htm并且.htm文件没有交给ASP.NET的ISAPI处理, 那么根据服务器速度在每个Frame页面生成不同的SessionID, 再刷新后相同都等于最后一个SessionID.
解决办法是将.htm后缀改成.aspx, 或者将.htm文件交给ASP.NET的ISAPI处理.
(5)Session_End事件:
1. Session_End仅在InProc模式中可用
2. 关闭浏览器,Session_End是不会触发的。HTTP是一种无状态协议,服务器没有办法知道你的浏览器是否已经关闭。
3. 当Session因为时间过期或调用Session.Abandon时,Session_End才会触发.Session.Clear()仅仅是清除数据,但没有删除session。
4. Session_End由一个后台线程触发,使用工作者进程账号运行. 所以程序不会通知发生的错误.
5. 在Session_End访问数据库要考虑权限问题. Session_End是用运行工作者进程(aspnet_wp.exe)的帐号运行的,这个账号可以在machine.config中指定。因此,在Session_End中,如果使用integrity security连接SQL,它将使用工作者进程账号身份连接,这可能会引起登录失败.
6.因为Session_End是有独立线程出发的, 所以在Session_End中无法使用HttpContext对象(Request,Response,Server等对象都在HttpContext中), 即无法使用 Response.Redirect 和Server.Transfer等方法.
七.总结
我已经使用SqlServer模式对公司的多台服务器实现了Session共享, 服务器重启也不会导致用户预定过程重新开始(预定过程需要的Session不会丢失). 希望本文对具体的Session服务器搭建人员有所帮助.
关于搭建Session服务器(转载)的更多相关文章
- Ubuntu 14.04 下搭建SVN服务器 (转载自 http://www.linuxidc.com/Linux/2015-01/111956.htm)-------------我所用到是红色字体
http://www.linuxidc.com/Linux/2015-01/111956.htm Ubuntu 14.04 下搭建SVN服务器 svn:// 安装软件包: sudo apt-get i ...
- 使用VisualSVN Server搭建SVN服务器(转载)
转载于http://www.cnblogs.com/greywolf/archive/2013/01/28/2879952.html 使用 VisualSVN Server来实现主要的 SVN功能则要 ...
- Linux(Centos7)下搭建SVN服务器 (转载)
系统环境:centos7.2 第一步:通过yum命令安装svnserve,命令如下: yum -y install subversion 此命令会全自动安装svn服务器相关服务和依赖,安装完成会自动停 ...
- SVN服务器搭建和使用-转载
SVN服务器搭建和使用(一)-转载 原文地址:http://www.cnblogs.com/xiaobaihome/archive/2012/03/20/2407610.html Subversion ...
- Win7服务器搭建实例教程:教你Win7如何搭建Web服务器【转载】
原文地址:http://www.pc841.com/article/20140607-30534.html 局域网Web服务器的主要功能是实现资源共享,同时借助于局域网服务器访问页面可有效的实现信息的 ...
- 搭建Git服务器(转载)
转自:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137583770360 ...
- Linux 搭建FTP服务器
介绍 本章主要介绍在Linux中搭建FTP服务器的过程,需要掌握的要点是配置文件的合理配置. 知识点 在linux中使用的FTP是vsftp FTP可以有三种登入方式分别是: 匿名登录方式:不需要用户 ...
- 自己家里搭建NAS服务器有什么好方案?
转自:https://www.zhihu.com/question/21359049 作者:陈二发链接:https://www.zhihu.com/question/21359049/answer/6 ...
- 使用Gitosis搭建Git服务器
使用Gitosis搭建Git服务器 作者: JeremyWei | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明 网址: http://weizhifeng.net/build- ...
随机推荐
- Linux LVM(逻辑卷管理)
Lvm基本应用 什么是LVM? LVM 的全称是 Logical Volume Manager.中文为逻辑卷管理.它是Linux对磁盘分区的一种管理机制.它在传统的硬盘(或硬盘分区)和文件系统之间建立 ...
- HIToj--1076--Ordered Fractions(水题)
Ordered Fractions Source : Unknown Time limit : 3 sec Memory limit : 32 M Submitted : 1510, Ac ...
- SQL调用Webservices
IF NOT object_id('proc_CallWebServices') IS NULL DROP PROCEDURE proc_CallWebServices GO CREATE PROCE ...
- Weka中数据挖掘与机器学习系列之Weka Package Manager安装所需WEKA的附加算法包出错问题解决方案总结(八)
不多说,直接上干货! Weka中数据挖掘与机器学习系列之Weka系统安装(四) Weka中数据挖掘与机器学习系列之Weka3.7和3.9不同版本共存(七) 情况1 对于在Weka里,通过Weka P ...
- css历史
CSS目前最新版本为CSS3,是能够真正做到网页表现与内容分离的一种样式设计语言.相对于传统HTML的表现而言,CSS能够对网页中的对象的位置排版进行像素级的精确控制,支持几乎所有的字体字号样式,拥有 ...
- happy Mom ——php mysqli DES加密
看完<爱你就像爱生命>这本书,真的看出小波哥很有才,跟小波哥比起来,我唯一拿的出手的可能就是我比他的颜值了.想起一句话,人不是因为美丽而可爱,而是因为可爱而美丽.所以我对我的要求是,继续修 ...
- CMD规范学习笔记——基于SEAJS实现
CMD(Common Module Definition):该规范明确了模块的书写格式和基本交互规则.通常一个模块就是一个JS文件. 通过define关键字来定义模块,最基本的格式为: define( ...
- request中文乱码解决
String str = new String(request.getParameter("参数名").getBytes("iso-8859-1"), &quo ...
- BRep Shapes Based on Tessellated Geometry
BRep Shapes Based on Tessellated Geometry eryar@163.com Key Words. BRep Shape, Tessellated Geometry, ...
- 想学android进来看看吧~ ~
我深知学校里面有非常多同学想学习新的知识,而苦于没有指导. 事实上我想说的是,非常多东西须要靠自己,须要借助度娘,谷歌的.当然有人指导是最好的了. 对于刚接触android是不是也想做出像以下的效果: ...