Session持久化

ASP.NET Session丢失原因:

由于Asp.net程序是默认配置,所以Web.Config文件中关于Session的设定如下:

< sessionState mode='InProc' stateConnectionString='tcpip=127.0.0.1:42424' sqlConnectionString='data source=127.0.0.1;Trusted_Connection=yes' cookieless='true' timeout='60'/>

我们会发现sessionState标签中有个属性mode,它可以有3种取值:InProc、StateServer?SQLServer(大小写敏感)。默认情况下是InProc,也就是将Session保存在进程内(IIS5是aspnet_wp.exe,而IIS6是W3wp.exe),这个进程不稳定,在某些事件发生时,进程会重起,所以造成了存储在该进程内的Session丢失。

哪些情况下该进程会重起呢?微软的一篇文章告诉了我们:

1、配置文件中processModel标签的memoryLimit属性

2、Global.asax或者Web.config文件被更改

3、Bin文件夹中的Web程序(DLL)被修改

4、杀毒软件扫描了一些.config文件。

 

 

不只是session,asp.net中application、cache都很容易丢失,特别是当任何一个访问的用户中遇到异常,都很容易把所有内存中的数据丢失掉。

.net 为了session丢失提供了一个解决方案,他可以把session状态保存在一个独立的进程中,这个进程不受asp.net的进程管理,因此即使 asp.net服务进程回收内存也不会导致session丢失。而这个过程也很简单,先在服务中aspnet_state服务开启(最好选择自动),而程序中,我们需要在web.config中配置
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424"></sessionState>
就可以了,关键在stateConnectionString中配置进程服务器的地址和端口(一般默认是42424),也就是说进程服务可以在别的服务器上。还有一点需要注意,session中的数据必须要可以被序列化,其实也很简单,比如,我们要把一个CUser类型的数据保存在session中,只需要在cuser定义前使用一个标签[Serializable()]就可以了。

除次之外,asp.net甚至可以将状态保存在数据库中,这样,即使服务器重起,用户状态也不会丢失。

 

 

 关于Session持久化这方面的话题,有很多人已经写过了,但是,毕竟这是我的项目经验,更加真实,可用。
    
进入主题。

情景一,Session ID在客户端的状态
        
情景一中,saved in cookies
情况
        
ID保存在client端的Cookies集合中
        缺点是,如果client端的cookie被禁用,那么ID无法保存
        
设置cookieless="false"

<sessionState
mode=
"InProc"
stateConnectionString=
"tcpip=127.0.0.1:42424"
sqlConnectionString=
"datasource=127.0.0.1;userid=sa;password="
cookieless=
"false"
timeout="20"/>

        情景一中,saved in url情况
        
MS为了解决cookie被禁时,也能正常保存ID,在.net2.0中可以把ID保存在URL中.
        
设置cookieless="true"

<sessionState
    
mode="InProc"
    
stateConnectionString="tcpip=127.0.0.1:42424"
    
sqlConnectionString="datasource=127.0.0.1;userid=sa;password="
    
cookieless="true"
    
timeout="20"/>

       情景二,Session状态在服务器中的三中模式,进程内、进程外、数据库。
            
情景二中,saved in 进程内
            
设置mode="InProc"
            
优点;保存在本机内存中,无需跨网络,访问内存速度快
            
缺点;如果IIS进程发生异常或者WebSite有文件变更,都被asp.netRuntime监视,然后重新设置Session状态

       <sessionState
            
mode="InProc"
          
stateConnectionString="tcpip=127.0.0.1:42424"
            
sqlConnectionString="datasource=127.0.0.1;userid=sa;password="
            
cookieless="false"
            
timeout="20"/>

           情景二中,saved in 进程外
           
设置mode="StateServer",启动asp.net状态服务
           
定位注册表
            
“HKEY_LOCAL_MACHINE/SYSTEM/ControlSett001/Services/aspnet_state/Parameters“修改AllowRemoteConnection=1,Port=42424
           注意这些参数都是十进制类型,且这些设置是在访问远程asp.net状态服务的必要设置。
           
优点;稳定,即使关闭WWW服务,只要启动asp.net状态服务,Session状态依然存在,不信你试试。
           
如果把状态保存在非本机上只需修改上面的注册表,修改stateConnectionString="tcpip=RemoteIP:Remoteport",
           如果状态保存在远程机上的asp.net状态服务中,那么当页面关闭的时候,Session状态马上失效,
           不管你的状态保存时间设置时间有多长,一律失效
           不信可以考试试,^-^。

    <sessionState
        
mode="StateServer"
    
    stateConnectionString="tcpip=127.0.0.1:42424"
        
sqlConnectionString="datasource=127.0.0.1;userid=sa;password="
        cookieless="false"
    
    timeout="20"/>

       情景二中,saved in 数据库
       
设置
       
mode="SQLServer"
       
sqlConnectionString="datasource=127.0.0.1;userid=sa;password="
       
启动SqlServer和SqlServerAgent。
       
定位到[systemdrive]\winnt\Microsoft.NET\Framework\[version]\
       
执行InstallSqlState.sql。
       
然后我们看tempdb数据库中多了两个用户表,而且多了一个ASPstate的空库,ASPStateTempApplicationsASPStateTempApplications表中
       存储的是应用程序信息,每个应用程序在启动的时候在这里会注册一条记录,包括应用程序的
ID(通过哈希算法生成的)和应用程序名称,
       实际上Session信息是存储在了tempdb数据库的ASPStateTempSessions表中,另外查看管理->SQLServer代理->作业,
       发现也多了一个叫做
ASPState_Job_DeleteExpiredSessions的作业,这个作业实际上就是每分钟去ASPStateTempSessions表中删除过期的Session信息。

新建一个Asp.netWebSite,F5,一切OK
效果图形 
两张表
 
ASPStateTempApplications表的数据

ASPStateTempSessions表的数据

ASPState_Job_DeleteExpiredSessions作业


需要注意的地方;

一,ASPStateTempApplicationsASPStateTempSessions表的权限用户是sa,既管理员。
二,启动MsSqlSeverAgent用来执行清除过期Session的作业ASPState_Job_DeleteExpiredSessions
三,如果MsSqlServerWebSite不在同一台机器上,那么设置sqlConnectionString="datasource=RemoteIP;userid=userName;password=userpwd"

posted @ 2009-12-31 17:26  小师傅  阅读(432)  评论(0编辑  收藏  举报