zoukankan      html  css  js  c++  java
  • 温故而知新:Asp.Net中如何正确使用Session

    Asp.Net中的Session要比Asp中的Session灵活和强大很多,同时也复杂很多;看到有一些Asp.Net开发人员报怨说Session不稳定,莫名其妙的丢失,其实这正是Asp.Net改进的地方之一.

    我们知道Session与Cookie最大的区别在于:Cookie信息全部存放于客户端,Session则只是将一个ID存放在客户端做为与服务端验证的标记,而真正的数据都是放在服务端的内存之中的。

    在传统web编程语言(比如asp)中,session的过期完全是按照TimeOut来老老实实处理的,超时值默认是20分钟,但问题是:通常有很多用户只看一眼网页,然后就关浏览器走人了,这种情况下,服务端内存里还长久保存着Session的数据,如果这种用户很多,对服务器资源无疑是一种浪费。

    而在Asp.Net中,Session的存储策略有好几种:

    默认情况下,系统采用的是InProc模式,即进程内模式。

    这种情况下,Session是保存在Asp.Net工作进程映射的内存中的,问题是Asp.Net工作进程为了维护良好的平均性能,会被系统经常回收。我们在IIS里可以配置自动回收(比如按时间周期回收,或者当内存使用达到多少值时自动回收),如下图即为IIS7中配置应用程序池回收参数的界面

     

    当Asp.Net工作进程被回收时,其映射的内存全部被清空并初始化,以便其它程序可以使用,所以Session也跟着一并消失了,就这是为什么Sesssion会无故消失的主要原因。

    当然默认的InProc模式也是性能最高的一种模式,如果您不能忍受这种“不稳定”,可以在web.config中把mode设置为StateServer模式

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

    这种情况下Session会被保存在Asp.Net进程之外的aspnet_state.exe进程中,这个进程不受asp.net进程回收的影响。

    但要注意:aspnet_state是以windows服务形式运行的,所以请先确保127.0.0.1对应的机器上该服务已经启动

    另外,我们也必须意识到:虽然StateServer模式下session会稳定很多,但是性能相对InProc而言是有损耗的(大概在15%~25%左右),因为系统内部要将session值序列化以后,保存到aspnet_state进程映射的内存中,读取的时候还要反序列化。

    这种模式还有一个优点:如果tcpip=127.0.0.1:42424中的IP地址指定为另外一台服务器,意味着可以将session保存在web服务器以外的机器上。

    session信息甚至还能保存到SqlServer数据库中:

    进入vs命令行模式,输入以下命令:

    aspnet_regsql -S 数据库实例名 -ssadd -U 连接用户名

    注意:数据库服务器得先启动Sql Server代理服务

    该命令运行后,将会自动创建一个AspState数据库,同时会在tempdb数据库下创建二张表ASPStateTempApplications与ASPStateTempSessions

    对应的web.config配置为:

    1
    <sessionState mode="SQLServer" sqlConnectionString="data source=JIMMYT61P;uid=sa;pwd=***"></sessionState>

    注:如果想把表直接创建在数据库ASPState中,刚才的命令行中,再加一个参数 -sstype p ,即:

    aspnet_regsql -S 数据库实例名 -ssadd -sstype p -U 连接用户名

    同样SqlServer模式在保存读取Session数据时,相对InProc模式也会有性能损耗(大约在25%左右),但利用SqlServer能实现Session数据的持久保存.

    最后再来看看mode中的另外二个值: Off与Custom

    Off 相当于禁用了session,就不多说了

    Custom 允许开发人员自己定义Session如何存储,相当于提供了一个可供编程的开发接口(我从来没用过,所以...也谈不出很深的道道来,呵呵)

    综合一下:

    InProc性能最高,但是有可能会使session无故丢失,而且这种模式无法适用于web服务器集群或负载均衡场景(因为多台服务器之间无法实现Session同步),StateServer与SqlServer可应用于web服务器集群场景,但是性能有所降低;如果希望Session能持久化保存,SqlServer是唯一的内置方案。

    最后谈点个人经验:

    一般情况下,我倾向于使用cookie,从而减少对服务器资源的消耗,但是这也要找一个平衡点,因为服务端代码中要得到客户端的cookie,也就意味着cookie文件必须通过浏览器传递到服务器,同样会消耗网络带宽。

    另外:在一些博客系统中,比如用户写文章时,如果中途离开了下,然后继续写,等到保存时会发现session已经失效,页面跳到登录页,辛苦打了N多字却没了!这时可考虑用代码一直维系session,即麒麟兄弟的心跳思想:让你的网站"心跳"起来 ,或者用ajax每隔几分钟自动保存一次

    再者:从安全性上讲,伪造session要比cookie难得多,相对更安全一些。

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com 
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    block的是发送信号的线程,又不是处理槽函数的线程
  • 原文地址:https://www.cnblogs.com/withoutaword/p/2851168.html
Copyright © 2011-2022 走看看