Session数据无故丢失及解决方案
用过Session的应该都知道Session的缺点:Session不稳定,保存的数据莫名其妙的丢失。为什么?
在回答这个问题之前,先看看web.config配置文件的<system.web> </system.web>节点下的<sessionState></sessionState>节点的属性及对应的属性值
必须属性:mode:Off:不使用Session功能
InProc:将Session存储在进程内,就是ASP中的存储方式,这是默认值
SateServer:将Session存储在独立的状态服务中
SQLServer:将Session存储在SQL Server中
Custom:允许开发人员自己定义Session如何存储
可选属性:cookieless:设置客户端的Session信息存储到哪里,默认Cookie模式
timeout:设置经过多少分钟后服务器自动放弃Session信息。默认为20分钟
stateConnectionString:设置将Session信息存储在状态服务中时使用的服务器名称和端口号,例如:"tcpip=127.0.0.1:8888”。
当mode的值是StateServer时,这个属性是必需的
sqlConnectionString:设置与SQL Server连接时的连接字符串。例如"data source=localhost;Integrated Security=SSPI;"。
当mode的值是SQLServer时,这个属性是必需的
stateNetWorkTimeout:设置当使用StateServer模式存储Session状态时,经过多少秒空闲后,断开Web服务器与存储状态信息的服务器的 TCP/IP连接的。默认值是10秒
从属性mode的选项值中可以知道,默认情况下,系统采用的是InProc模式,即进程内模式。这种情况下,Session是保存在Asp.Net工作进程映射的内存中的,问题是Asp.Net工作进程为了维护良好的平均性能,会被系统经常回收。当Asp.Net工作进程被回收时,其映射的内存全部被清空并初始化,以便其它程序可以使用,所以Session也跟着一并消失了,就这是为什么Sesssion会无故消失的主要原因。
找到问题所在,那怎么解决呢?答案就是可以将Session存储在进程外。
StateServer模式:
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:8888"></sessionState>
这种模式下Session会被保存在Asp.Net进程之外的aspnet_state.exe进程中,这个进程不受asp.net进程回收的影响。但要注意:aspnet_state是以windows服务形式运行的,所以请先确保127.0.0.1对应的机器上该服务已经启动(ASP.NET State Service服务)。
另外如果tcpip=127.0.0.1:42424中的IP地址指定为另外一台服务器,意味着可以将session保存在web服务器以外的机器上
SQLServer模式:
<sessionState mode="SQLServer" sqlConnectionString="data source=localhost; Integrated Security=SSPI"></sessionState>
或
<sessionState mode="SQLServer" sqlConnectionString="data source=.;uid=sa;pwd=***"></sessionState
在vs命令提示下输入:aspnet_regsql -S 数据库实例名 -ssadd -U 连接用户名.注意:数据库服务器得先启动Sql Server代理服务
该命令运行后,将会自动创建一个AspState数据库,同时会在tempdb数据库下创建二张表ASPStateTempApplications与ASPStateTempSessions
如果想把表直接创建在数据库ASPState中,刚才的命令行中,再加一个参数 -sstype,即:aspnet_regsql -S 数据库实例名 -ssadd -sstype p -U 连接用户名
Tag:
Integrated Security=SSPI的意思是使用Windows集成身份验证,这样,访问数据库将以ASP.NET的身份进行,通过如此配置,能够获得比使用userid=sa;password=口令 的SQL Server验证方式更好的安全性
总结:
InProc性能最高,Session存储的数据可能会无故丢失,而且这种模式无法适用于web服务器集群或负载均衡场景(因为多台服务器之间无法实现Session同步),StateServer与SqlServer可应用于web服务器集群场景,但是性能有所降低;如果希望Session能持久化保存,SqlServer是唯一的内置方案