温故而知新:Asp.Net中如何正确使用Session

原文链接作者:菩提树下的杨过
出处:http://yjmyzz.cnblogs.com

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模式

<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配置为:

<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 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

时间: 2024-08-24 03:29:39

温故而知新:Asp.Net中如何正确使用Session的相关文章

ASP.NET中利用Application和Session统计在线人数、历史访问量

先来简单说一下ASP.NET中的Application和Session 下图是我们非常熟悉的Web应用程序的结构: 在这张图中,Web服务器中运行的Web应用程序就是我们所说的Application,每个客户端与Web服务器之间建立的连接就可以看做是一个Session.比如现在服务器端运行的是一个论坛系统,那么现在这个正运行在服务器端的论坛系统的软件就可以看做Application,而每个在线的用户与之建立的连接就相当于一个Session. 那么很容易就会理解,Application是共享的,相

ASP.NET中自定义类使用Session保存信息

Session是Page类的内置对象,可以直接使用Session,但是普通的类,比如一般处理类就无法直接使用.之前我在Handler类中使用类似System.Web.HttpContext.Current.Session["userid"];但是调试显示System.Web.HttpContext.Current.Session一直为null. 解决办法:让自定义的类实现IRequiresSessionState接口,同时加入:using System.Web.SessionState

ASP.Net中无刷新执行Session身份验证

在写一个客户的B/S结构应用程序时,突然发现一个技巧,不知道是否是MS的一个BUG,给相关的有研究的朋友原先考虑写一个检查Session的类,Session失效后,必须转向登陆页面,可每一个调用该类的页面,在不同的WEB路径下,所以转到登陆页面的URL都不同,每个页面都要调用和设置登陆页面路径,所以实际应用就放弃了这一想法后来考虑到不如写一个检查Session失效的页面,由客户端每一秒都刷新一下,就可以在一个页面中调用,但通过FRAME嵌入该ASPX老时有请求发出,不太好看,虽然该页面是隐藏的.

Asp.net中的一个判断session是否合法的做法

1 if (Session["UserID"] == "" || Session["UserID"] == null) 2 { 3     Response.Redirect("../Login.aspx?m=登录已超时,请重新登陆!"); 4 } 一直我都觉得这个方法很不好,非常不好,但是一直也没找到好的方法,刚才突然就想到和匿名方法,结合??运算符,如果session为空,那么就不合法的了, 可以用来判断用户是否登录. 由

ASP.NET中的Session怎么正确使用

Session对象用于存储从一个用户开始访问某个特定的aspx的页面起,到用户离开为止,特定的用户会话所需要的信息.用户在应用程序的页面切换时,Session对象的变量不会被清除. 对 于一个Web应用程序而言,所有用户访问到的Application对象的内容是完全一样的:而不同用户会话访问到的Session对象的内容则各不相 同. Session可以保存变量,该变量只能供一个用户使用,也就是说,每一个网页浏览者都有自己的Session对象变量,即Session对象具有唯一 性. 什么是Sess

asp.net中session的原理及应用

Session简介丶特性 1.Session是一种Web会话中的常用状态之一. 2.Session提供了一种把信息保存在服务器内存中的方式.他能储存任何数据类型,包含自定义对象. 3.每个客户端的Seesion是独立存储的. 4.在整个会话过程中,只要SessionID的cookie不丢失,都会保存Session信息的. 5.Session不能跨进程访问,只能由该会话的用户访问.应为提取Session数据的id标识是以Cookie的方式保存到访问者浏览器的缓存里的. 6.当会话终止,或过期时,服

ASP.NET中Session的sessionState 4种mode模式

1. sessionState的4种mode模式 在ASP.NET中Session的sessionState的4中mode模式:Off.InProc.StateServer及SqlServer. 2. Off模式 <sessionState mode="Off"></sessionState> 关闭模式,即不需要使用Session. 单个页面关闭Session: <%@ Page EnableSessionState="false" %

asp.net中一般处理程序中添加session

asp.net中使用一般处理程序(.ashx)添加session,利用context.session["xxx"] = value的方式把值保存到session:运行的时候会出现该对象尚未引用. 解决办法:1,在一般处理程序的类后面添加IRequiresSessionState.例如public class xxx : IHttpHandler, IRequiresSessionState. 2,引入session所使用的类库,using System.Web.SessionState

ASP.NET中在一般处理程序中使用session的简单介绍

这篇文章介绍了ASP.NET中在一般处理程序中使用session,有需要的朋友可以参考一下 <%@ WebHandler Language="C#" Class="ChangePwd" %> using System; using System.Web; using System.Web.SessionState; public class ChangePwd : IHttpHandler, IReadOnlySessionState { public