首页 > 代码库 > 进程外session

进程外session

引言

       http是一个无状态连接的协议,而http协议是万维网使用的协议,所以,我们的网页在最根上都是无状态的连接,即:一个用户发出一个请求,服务器端处理这个请求,然后,将结果返回这个用户,然后,他们之间就没有任何的联系了,但是呢,在我们实际的开发网站中并不是这样的,这个是因为,我们使用的开发平台弥补了这个问题。

       .net平台在处理http的无状态连接问题时,使用了cookie,session,application,viewstate,隐藏域等等,本篇博客主要讲的是Session。

       session是会话级的对象,当我们程序使用它时,那么服务器程序就会为每个使用该页面的用户创建一片空间,这样来实现有状态的连接,从这里来看,我们可以得出一个缺点,如果有很多的用户访问这个页面,那么服务器岂不是开辟出很多的数据空间,这样是非常的浪费内存资源的。

       从这个层次上理解,我们使用Session勉强说得过去,因为,内存资源少了,但是程序还是可以运行的,但是,如果从IIS的稳定性上说,那就完蛋了。

       微软提供的IIS服务器非常的强大,非常的稳定,它的这种稳定的维护是这样的:阻塞处理不了请求时,那就自动重启。而且,我们换可以进行应用程序池回收的相应设置,这个非常的恐怖,你想IIS重启或应用程序池被回收了,那么我们程序的Session的数据不就什么也没有了吗?想一想此时对于一个刚登上该网站的用户来说,他会有什么反应?

       上面的Session是进程内Session,当然,有进程内Session,就会有进程外Session,从上面说asp.net的Session的缺点上说,换不能完全引入本片博客的主题,因为,对于小型的网站来说,上面的进程内Session的缺点,那都不是事,并且,估计也不会经常发生那种事,用户量少嘛!那么,另一个引题的内容是什么呢?

       另一个引出进程外Session的原因是集群web程序,开发了一个网站,我们要将这么一个同一份程序,部署在不同的计算机上,实现集群web程序,实现web集群程序后,运行的效果是怎样的呢?

       举个例子,我们把同一份web程序部署在A、B和C这3个计算机上,此时,同一个用户访问这个网站的时候,第一时间访问的是A计算机的程序,第二时间可能访问的就是B计算机的程序了,第三时间可能访问的就是C计算机上的程序了,这个是web集群程序实现后的效果,当然,要想实现这么一个效果,我们首先要考虑的是状态数据的共享,很明显,如果此时我们的Session是进程内的话,那么我访问A机的程序需要登录一遍,访问B机的程序时,也需要登录一遍,所以,我们的进程外Session也就出来了。


微软提供的进程外Session服务

概述

       微软自身提供了以进程的Session服务,我们使用时,需要将其开启:开始—计算机—管理—ASP.net状态服务,或命令窗口输入services.msc。另外,我们需要修改一下注册表,使其支持远程连接,打开注册表,找到这个:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection,并将其修改为1。

缓存在内存

       配置文件添加如下节点

       <sessionStatemode="StateServer"stateConnectionString="tcpip=localhost:42424" timeout="30" cookieless="false" ></sessionState>

       然后,直接向平常一样使用Session就行了

缓存在数据库

       创建相应存放Session数据的数据库和表,数据库我们可以使用业务数据库,也可以自己单独的创建一个,表的创建,不用我们操作,微软给我们提供了相应的sql了,我们可以在相应版本的.net framework中找到那个sql,然后,在SqlServer中执行,也可以运行如下命令:aspnet_regsql.exe -S localhost\Server -UuserName -P password -ssadd -sstype c -d SqlSessionTest,localhost\Server:具体的一个数据库服务器;SqlSessionTest:数据库名称;执行该命令后会多出两个表

       配置文件中添加如下节点

       <sessionState mode="SQLServer"allowCustomSqlDatabase="true" sqlConnectionString="Data Source=localhost\Server; InitialCatalog=SqlSessionTest; uid=userName;pwd=password"></sessionState>

       完成上述操作后,向平常使用Session就行。

       注意:

              程序和进程外Session之间的传递,使用的Socket,所以,当涉及到将一个自定义类的对象保存在Session上时,我们需要在该类上打上序列化标签:[Serializable];

       微软提供的进程外Session的机制,效率不是很好,所以,一般不会使用缓存在内存,更不会使用缓存在数据库,解决这个问题,我们可以使用Memcached模拟Session


Memcached模拟Session服务

       Session是微软解决无状态连接提供的一个机制,解决无状态的主要问题就是,用户和服务器数据之间的对接,在Session中的这种对接,使用的是SessionID,SessionID存放在浏览器中,SessionID存放在服务器中,而且,SessionID是唯一的,这样就实现了之间的对接。

       我们是用Memcached模拟Session服务,也是这么一个原理,用户第一次登陆的时候,我们生成一个GUID保存在Cookie上,并且,将这个GUID作为Memcached中的key,然后,我们就直接往上面进行添加就行了,要想使其模拟的Session使用时,更加的灵活和逼真,我们的Value可以使用Dictionary类型,当然,我们需要自己封装一个类,然后,类里面自己写上相应的方法。

       在封装这个类的时候,我们需要注意,此时使用的是Memcached,要是之后使用Redis呢?要是之后,此时,我们最好使用观察者模式进行相应的设计,为了达到那种配置一下就行了地步,我们需要将添加观察者等方法去掉,直接使用spring.net给其注入到里面。   


总结

       没有最好的,只有适合的。根据自己的项目适当的选择相应的方案。

进程外session