[转]Session服务器配置指南与使用经验
2015-03-17 17:14
471 查看
本文转自:/article/4677253.html
在向服务器发送的HTTP请求中会包含SessionID,服务器端根据SessionID获取获取此用户的Session信息.
很多初级开发人员不知道SessionID和Cookies的关系,所以常常认为两者没有联系.这是不正确的.正是因为SessionID保存在Cookies中,所以在我们保存Cookies的时候,一定要注意不要因为Cookies的大小和个数问题而导致SessionID对象.在我们的程序中,对SessionID的Cookies有特殊的处理:
.NET提供了5种保存Seission的方式:
我们可以在Web.Config中配置程序使用的Session存储方式.默认情况下是InProc,即保存在IIS进程中.关于Off,InProc和Customer本文不做讲解.相关文章大家都可以在网上搜索到.
下面主要讲解StateServer和SQLServer的应用.
2.修改注册表:[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\aspnet_state\Parameters]
设置AllowRemoteConnection=1,设置Port=42424(十进制,默认即为42424)
Port是服务的端口号
AllowRemoteConnection表示是否允许其他机器连接,0为仅能本机使用,1为可以供其他机器使用.
没有则添加(默认使用的是InProc方式)
上面的参数我们可以根据需要修改.
.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会自己创建新的数据库
使用举例:
aspnet_regsql.exe-S.-Usa-P123456-ssadd-sstypep
-S参数:
表示数据库实例名称.可以用"."表示本机.
-U和-P参数:
表示用户名和密码.
-E参数:
可以再-U–P与-E中选择一组.–E表示以当前系统用户通过windows身份验证登录数据库,-U-P则是使用SqlServer用户登录数据库.
-ssadd/–ssremove参数:
-ssadd表示是添加Session数据库,-ssremove表示移除Session数据库.
sstype参数:
如果使用了自定义的数据库名称,则还需要制定allowCustomSqlDatabase属性并在数据库连接串中指定数据库:
2.要保存在Session中的对象是可序列化的。
3.为了在webfarm中的不同web服务器上维护sessionstate,IISMetabase中的网站应用程序路径(如\LM\W3SVC\2)应该在所有的服务器上保持一致(大小写敏感).
4.ASP.NET处理Session是在Machine.Config中配置的HttpModuel模块,在.NET的安装目录下的Config文件夹中,查看Web.Config(1.1版本是在Machine.Config):
确认此模块是否存在.
5.StateServer不支持负载均衡,所以如果大并发推荐使用SqlServer模式,可以享受到SqlServer的高性能和安全性.虽然存储效率会有下降.
6.需要让所有机器的MachineKey相同.在Machine.Config中配置:
2.如果使用了默认是数据库,则在客户端配置文件中的数据库链接字符串的用户,需要拥有ASPState和tempdb两个库的dbowner权限.
3.在SQLServer模式下,session过期是由SQLAgent使用一个注册任务完成的,要确认SQLAgent已经运行。否则无法清理过期的Session数据,会导致数据库数据一直增加.
4.如果使用SqlServer模式时,对于Web场中的各服务器的ASP.NET应用程序路径必须是相同的。请在IIS配置数据库中对Web场中的所有Web服务器进行Web站点的应用程序路径同步。大小写一定要相同,因为Web站点的应用程序路径是区分大小写的。
5.需要让所有机器的MachineKey相同.在Machine.Config中配置:
http://msdn.microsoft.com/zh-cn/library/aa479313.aspx
2.在不同的应用程序或一个网站的不同虚拟目录之间无法共享Session
3.Session的过期时间是滑动时间.
4.Session存储.NET自带的值类型性能最优.存储对象会降低性能.
2.一般在Session超时或删除之后,SessionID保持不变.因为Session过期后会在服务器端清除数据,但是SessionID保存在用户浏览器上,所以只要浏览器不关闭则HTTP头中的SessionID保持不变.
3.关闭浏览器后再访问,SessionID会不同.
4.每打开一个IE6窗口,SessionID都不同,在IE6中两个窗口的Session不能共享.
5.FireFox的标签页和新的FireFox窗口,SessionID都相同,在FF的窗口和标签页上Session能共享.
6.对于包含FrameSet的页面,比如:
如果后缀名是.htm并且.htm文件没有交给ASP.NET的ISAPI处理,那么根据服务器速度在每个Frame页面生成不同的SessionID,再刷新后相同都等于最后一个SessionID.
解决办法是将.htm后缀改成.aspx,或者将.htm文件交给ASP.NET的ISAPI处理.
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中,如果使用integritysecurity连接SQL,它将使用工作者进程账号身份连接,这可能会引起登录失败.
6.因为Session_End是有独立线程出发的,所以在Session_End中无法使用HttpContext对象(Request,Response,Server等对象都在HttpContext中),即无法使用Response.Redirect和Server.Transfer等方法.
参考文献:
使用一个SQL数据库SQLServer会话状态的所有应用程序可能导致瓶颈
http://support.microsoft.com/kb/836680/zh-cn
ASP.NET中Session实现原理浅析[1]/[2]
/article/4792296.html
/article/4792298.html
理解SessionState模式+ASP.NETSESSION丢失FAQ[翻译]
http://www.cnblogs.com/tonyqus/archive/2006/10/24/522618.html
作者:张子秋出处:http://www.cnblogs.com/zhangziqiu/本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
一.摘要
所有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> ///<paramname="day"></param> ///<returns></returns> publicboolSetCookie(intday) { stringCookieName=GetType().ToString(); HttpCookieSessionCookie=null; //对SessionId进行备份. if(HttpContext.Current.Request.Cookies["ASP.NET_SessionId"]!=null) { stringSesssionId=HttpContext.Current.Request.Cookies["ASP.NET_SessionId"].Value.ToString(); SessionCookie=newHttpCookie("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); } } returntrue; }
三.搭建Session服务器的几种方式
将Session保存在独立的服务器中可以实现在多台Web服务器之间共享Session.虽然我们也可以自己开发Session存储系统,但是使用ASP.NET自带的存储机制将更加便捷..NET提供了5种保存Seission的方式:
方式名称 | 存储方式 | 性能 |
Off | 设置为不使用Session功能 | 无 |
InProc | 设置为将Session存储在进程内,就是ASP中的存储方式,这是默认值。 | 性能最高 |
StateServer | 设置为将Session存储在独立的状态服务中。通常是aspnet_state.exe进程. | 性能损失10-15% |
SQLServer | 设置将Session存储在SQLServer中。 | 性能损失10-20% |
Customer | 自定制的存储方案 | 由实现方式确定 |
下面主要讲解StateServer和SQLServer的应用.
四.使用StateServer模式搭建Session服务器
(1)服务器端配置
1.启动Asp.netStateservice服务.(这个服务默认的状态为手动.修改为自动并启动.)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.NET1.0和1.1版本请使用方式a,2.0即以上版本请使用方式b.a.使用SQL文件创建Session数据库
在ASP.NET1.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.NET2.0版本后微软提供了aspnet_regsql.exe工具可以方便的配置Session数据库.该工具位于Web服务器上的"系统根目录\Microsoft.NET\Framework\版本号"文件夹中.使用举例:
aspnet_regsql.exe-S.-Usa-P123456-ssadd-sstypep
-S参数:
表示数据库实例名称.可以用"."表示本机.
-U和-P参数:
表示用户名和密码.
-E参数:
可以再-U–P与-E中选择一组.–E表示以当前系统用户通过windows身份验证登录数据库,-U-P则是使用SqlServer用户登录数据库.
-ssadd/–ssremove参数:
-ssadd表示是添加Session数据库,-ssremove表示移除Session数据库.
sstype参数:
选项 | 说明 |
t | 将会话数据存储到SQLServertempdb数据库中。这是默认设置。如果将会话数据存储到tempdb数据库中,则在重新启动SQLServer时将丢失会话数据。 |
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.在webfarm中,请确认在所有的web服务器上有相同的<machineKey>2.要保存在Session中的对象是可序列化的。
3.为了在webfarm中的不同web服务器上维护sessionstate,IISMetabase中的网站应用程序路径(如\LM\W3SVC\2)应该在所有的服务器上保持一致(大小写敏感).
4.ASP.NET处理Session是在Machine.Config中配置的HttpModuel模块,在.NET的安装目录下的Config文件夹中,查看Web.Config(1.1版本是在Machine.Config):
<httpModules> ...
<addname="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过期是由SQLAgent使用一个注册任务完成的,要确认SQLAgent已经运行。否则无法清理过期的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.请使用微软提供的解决方案: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的页面,比如:
<framesetcols="25%,50%,25%">
<framesrc="SessionID.aspx">
<framesrc="SessionID.aspx">
<framesrc="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中,如果使用integritysecurity连接SQL,它将使用工作者进程账号身份连接,这可能会引起登录失败.
6.因为Session_End是有独立线程出发的,所以在Session_End中无法使用HttpContext对象(Request,Response,Server等对象都在HttpContext中),即无法使用Response.Redirect和Server.Transfer等方法.
七.总结
我已经使用SqlServer模式对公司的多台服务器实现了Session共享,服务器重启也不会导致用户预定过程重新开始(预定过程需要的Session不会丢失).希望本文对具体的Session服务器搭建人员有所帮助.参考文献:
使用一个SQL数据库SQLServer会话状态的所有应用程序可能导致瓶颈
ASP.NET中Session实现原理浅析[1]/[2]
理解SessionState模式+ASP.NETSESSION丢失FAQ[翻译]
作者:
相关文章推荐
- Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验【转】
- Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验
- 转:Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验 (转)
- Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验
- 转载:Session服务器配置指南与使用经验
- Session服务器配置指南与使用经验的深入解析
- Session服务器配置指南与使用经验的深入解析
- Session服务器配置指南与使用经验