ASP.NET性能优化之分布式Session

 

若是咱们正在使用Session,那么构建高性能可扩展的ASP.NET网站,就必须解决分布式Session的架构,由于单服务器的SESSION处理能力会很快出现性能瓶颈,这类问题也被称之为Session同步。微软有本身的分布式Session的解决方案,那就是SessionStateServer,咱们能够参考:html

ASP.NET Session State Partitioning  http://blog.maartenballiauw.be/post/2008/01/23/ASPNET-Session-State-Partitioning.aspxmysql

ASP.NET load balancing and ASP.NET state server  http://blog.maartenballiauw.be/post/2007/11/ASPNET-load-balancing-and-ASPNET-state-server-(aspnet_state).aspx算法

不过本文是要换一个方案,那就是使用Memcached来到达分布式SESSION的架构。Memcached做为分布式的缓存服务器已经被普遍应用在网站建设中。sql

 

一:Session的机制mongodb

Session是针对用户的,咱们也能够理解为是针对浏览器的。在浏览器首次访问ASP.NET网页的时候(网页没有关闭session功能),它会发送以下的HTTP头给客户端:数据库

image

浏览器在收到上面的HTTP头后,会将这个惟一的SESSIONID保存在本身的COOKIE中(只要没有禁用COOKIE,本文不讨论禁用COOKIE的案例,可参考本博文http://www.cnblogs.com/fish-li/archive/2011/07/31/2123191.html,写的很NICE)。当浏览器再次请求服务器进行访问的时候,它会在请求HTTP头中加入以下的标识,咱们能够看到,这个SESSIONID就是上面的SESSIONID:编程

image

浏览器和服务器间就是经过这样一种机制来确保用户SESSION的。浏览器

若是客户端浏览器禁用了Cookie会怎么样,咱们会发现每一次刷新浏览器Set-Cookie都是不一样的,而发送请求头中也永远不会出现Cookie标识。这个时候,咱们会发现Session失效了(固然,微软为了防止出现这种状况,容许咱们在sessionState中设置cookieless="true",用URL来传递sessionid)。缓存

二:Memcached Providers安全

我使用的Memcached客户端是Memcached Providers,下载完毕后,你会发现Memcached Providers已经提供了对分布式Session的支持功能。若是你还不会使用Memcached Providers,请参考此文Memcached Tip 1:使用Memcached Providers。Memcached Providers提供的示例是直接将SESSION存储在数据库,咱们能够经过配置来将SESSION支持存储在分布式SESSION的内存中,即,将下文中的dbType由SQL修改成none。:

image

使用Memcached Providers提供的分布式Session没有任何特别之处,由于Memcached Providers提供的SessionStateProvider类型实现的是ASP.NET中的SessionStateStoreProviderBase这个抽象类,咱们能够看到配置文件中指定了Session的处理类是SessionStateProvider,因此,ASP.NET在接受到客户端的请求后,会自觉滴使用SessionStateProvider来处理全部的SESSION,也正是这个类,完成了将SESSION读取和存储在Memcached中(若是设置了SQL,则会同步存储到SQLSERVER数据库)。

SESSION的设置和读取与传统没有任何区别,读:

?
Session["sname2"] = "sluminjxxi";
Session.Timeout = 2;

取:

?
Response.Write(Session["sname2"]);

 

三:为何要配置SQL

传统的SESSION的缺点,在仅使用dbType为none配置的时候都会存在。如Memcached的内存到达上限的时候会怎么办?Memcached使用LRU淘汰算法(最久未使用),在这里咱们不须要去细究这个算法在Memcached内部究竟是什么样一个机制,咱们只须要知道,在内存紧张的时候,即便SESSION时间未到,Memcached也有可能把它干掉。因此,保险的作法是,在Memcached之下,再加上SQLSERVER的持久化保存。若是缓存命中的,直接取缓存,若是缓存没命中的,则再到数据库中确认一次。固然,这样会带来一些性能损耗,可是倒是更安全的作法。

Memcached Providers提供的下载文件中,提供了初始化SESSION的一些脚本,正确执行后,它会生成以下一个表tblSessions,及若干存储过程:

image

tblSessions保存的是就是单独的Session,以下:

image

 

四:Memcached Providers的一个BUG

在当前的Memcached Providers(1.2版本)中关于SessionStateProvider(29520-TRUNK)是有一个BUG(我已提交到codeplex,相信他们的下一个版本应该能获得修正)的。若是咱们测试SESSION失效时间,发现只要通过一次刷新后,就永远是20分钟(即默认)。这源于在ReleaseItemExclusive这个重载方法中(该方法用于释放对会话数据存储区中项的锁定),对于Session的从新存储没有加上过时时间,以下:

image

注释掉的是Memcached Providers提供的源码,而正确的应该是我修正过的上一条。使用修正过的DLL,一切圆满了。

 

五:采用数据库存储SESSION的可扩展问题

随着访问量的进一步上升(固然,到了这种程度,说明网站作的很很成功,绝大部分的网站是不须要考虑这一步的),即使咱们使用了Memcached做缓存,使用单一的SQLSERVER存储SESSION仍旧带来了性能问题,在这种状况下,咱们对于数据库的设计能够采用水平分区的架构,即根据某种算法(能够根据SESSIONID,或者用户名等)将SESSION存储到不一样的数据库中。这个时候,若是咱们仍旧使用Memcached Providers,那么必须进一步修改源码了,由原先支持单一SQLSERVER服务器,编程支持多个服务器。固然,若是不喜欢SQLSERVER,还能够修改成支持mysql、mongodb、任何自定义的KEY-VALUE框架等等,此为后话,暂且不表

 

转:http://www.cnblogs.com/luminji/archive/2011/11/03/2195704.html

相关文章
相关标签/搜索