ASP.net session丢失
ASP.NET Session的实现:
asp.net的Session是基于HttpModule技术做的,HttpModule可以在请求被处理之前,对请求进行状态控制,由于Session本身就是用来做状态维护的,因此用HttpModule做Session是再合适不过了。
ASP.NET Session丢失原因:
1)Asp.net的Session是具有进程依赖性的。ASP Session状态存于IIS的进程中,也就是inetinfo.exe这个程序。所以当inetinfo.exe进程崩溃时,这些信息也就丢失。另外,重起或者关闭IIS服务都会造成信息的丢失。
2) bin目录中的文件被改写,asp.net有一种机制,为了保证dll重新编译之后,系统正常运行,它会重新启动一次网站进程,这时就会导致Session丢失,所以如果有access数据库位于bin目录,或者有其他文件被系统改写,就会导致Session丢失
3)文件夹选项中,如果没有打开“在单独的进程中打开文件夹窗口”,一旦新建一个窗口,系统可能认为是新的Session会话,而无法访问原来的Session,所以需要打开该选项,否则会导致Session丢失
4)有些杀病毒软件会去扫描您的Web.Config文件,或者Global.asax或者Web.config文件被更改,那时Session肯定掉,这是微软的说法。
5)程序内部里有让Session掉失的代码(Session.Abandon()),及服务器内存不足产生的。
6)似乎大部分的Session丢失是客户端引起的, 从客户端下手,看看cookie有没有打开,或者IE中的cookie数量限制(每个域20个cookie)可能导致session丢失
8)Session的时间设置是不是有问题,会不会因为超时造成丢失
8)使用web garden模式,且使用了InProc mode作为保存session的方式,默认情况下是InProc,保存20分钟。也就是将Session保存在进程内(IIS5是aspnet_wp.exe,而IIS6是W3wp.exe),这个进程不稳定,在某些事件发生时,进程会重起,所以造成了存储在该进程内的Session丢失。
9) 如果有些代码中使用客户端脚本,如javascript维护Session状态,就要尝试调试脚本,是不是因为脚本错误引起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,保存20分钟。也就是将Session保存在进程内(IIS5是aspnet_wp.exe,而IIS6是W3wp.exe),这个进程不稳定,在某些事件发生时,进程会重起,所以造成了存储在该进程内的Session丢失。
哪些情况下该进程会重起呢?
1、配置文件中processModel标签的memoryLimit属性
2、Global.asax或者Web.config文件被更改
3、Bin文件夹中的Web程序(DLL)被修改
4、杀毒软件扫描了一些.config文件。
更多的信息请参考PRB: Session variables are lost intermittently in ASP.NET applications
InProc 它允许“无Cookie”的会话,以及在服务器之外存储会话数据。ASP.NET会话状态模块在Web.config文件中像下面这样配置:
<sessionState mode="InProc" cookieless="false" timeout="20" />
在这个例子中,mode属性设为InProc(默认值),表明会话状态要由ASP.NET存储到内存中,而且默认不用Cookie来传递会话ID【<sessionState mode="InProc" cookieless="false" /> cookieless="false" :表示Session不需要Cookie传递;如果修改为cookieless="true":表示Session的ID在Cookie中传递,这样访问时地址栏中会出现多余的文字如:http://localhost:11209/Web/(S(lsua21yjunmcf245wnkogy55))/Index.aspx 】。采取这种方式,不管Cookie还是隐藏表单字段都用不着了。所以,即使网页中没有使用表单,也能加入会话。 但是这种方法,应用程序的状态将依赖于 ASP.NET进程, 当IIS进程崩溃或者正常重启时,保存在进程中的状态将丢失。
ASP.NET Session丢失解决办法:
sessionState标签中mode属性可以有三个取值,除了InProc之外,还可以为StateServer、SQLServer。这两种存Session的方法都是进程外的,所以当aspnet_wp.exe重起的时候,不会影响到Session。
1) StateServer是本机的一个服务,可以在系统服务里看到服务名为ASP.NET State Service的服务,默认情况是不启动的。当我们设定mode为StateServer之后,请手工将该服务启动。这样,我们就能利用本机的StateService服务来存储Session了,除非电脑重启或者StateService崩掉,否则Session是不会丢的(因Session超时被丢弃是正常的)。
除此之外,我们还可以将Session通过其他电脑的StateService来保存。具体的修改是这样的。在sessionState标签中,有stateConnectionString='tcpip=127.0.0.1:42424'属性,其中有个ip地址,默认为本机(127.0.0.1),你可以将其改成你所知的运行了StateService服务的电脑IP,这样就可以实现位于不同电脑上的Asp.net程序互通Session了。
将mode属性设为StateServer,也就是将会话数据存储到单独的内存缓冲区中,再由单独一台机器上运行的Windows服务来控制这个缓冲区。状态服务全称是“ASP.NET State Service ”(aspnet_state.exe),计算机管理-服务 里面即可看到此服务,启动该服务它由Web.config文件中的stateConnectionString属性来配置。该属性指定了服务所在的服务器,以及要监视的端口:
<sessionState mode="StateServer"
stateConnectionString="tcpip=myserver:42424"
cookieless="false" timeout="20" />
在这个例子中,状态服务在一台名为myserver的机器的42424端口(默认端口)运行。要在服务器上改变端口,可编辑HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters注册表项中的Port值。
显然,使用状态服务的优点在于进程隔离,并可在Web farm(网站群)中共享。 使用这种模式,会话状态的存储将不依赖于iis进程的失败或者重启,然而,一旦状态服务中止,所有会话数据都会丢失。换言之,状态服务不像SQL Server那样能持久存储数据;它只是将数据存储在内存中。
2) 如果你有更高的要求,需要在其他服务重启时Session也不丢失,可以考虑将mode设定成SQLServer,同样需要修改sqlConnectionString属性。
在使用StateServer或者SQLServer存储Session时,所有需要保存到Session的对象除了基本数据类型(默认的数据类型,如int、string等)外,都必须序列化。只需将[Serializable]标签放到要序列化的类前就可以了。
如:
[Serializable]
public class MyClass
{
......
}
ASP.NET还允许将会话数据存储到一个数据库服务器中,方法是将mode属性变成SqlServer。 在这种情况下,ASP.NET尝试将会话数据存储到由sqlConnectionString属性(其中包含数据源以及登录服务器所需的安全凭证)指定的SQL Server中。
为了用恰当的数据库对象来配置SQL erver,管理员还需要创建ASPState数据库,
方法是运行WinDir\Microsoft.Net\Framework\Version(如:v3.0)文件夹中的InstallSqlState.sql脚本(WinDir是服务器的Windows文件夹,而Version是你使用的.NET框架版本的安装文件夹)。要配置SQL服务器,可以在命令行中运行SQL Server 提供的命令行工具osql.exe
osql -S [ server name] -U [user] -P [password] -i InstallSqlState.sql
例如osql -S (local)\NetSDK -U sa -P "" -i InstallSqlState.sql
在这里用户名必须是SQL服务器上的sa帐号,或者具有同等权限的其他帐号。有兴趣的读者可以打开这个脚本文件来了解ASP.NET是如何和SQL Server配合实现状态管理的。 卸载这些表和存储过程,可以使用UninstallSqlState.sql脚本,使用方法与上面类似。做好必要的数据库准备工作后,将web.config 文件中的sessionstate 元素的mode改为"sqlserver",并且指定SQL连接字符串。具体如下:
mode="sqlserver" sqlConnectionString="data source=127.0.0.1; userid=sa; password="";
配置好SQL Server后,应用程序代码运行时就和InProc模式没有什么区别。但要注意的是,由于数据不存储在本地内存,所以存储会话状态的对象需要进行序列化和反序列化,以便通过网络传给数据库服务器,以及从数据库服务器传回。这当然会影响性能。通过在数据库中存储会话状态,可分别针对扩展性及可靠性来有效地平衡性能。另外,可以利用SQL Server的集群,使状态存储不依赖于单个的SQL Server,这样就可以为应用程序提供极大限度的可靠性。
ASP.NET Session丢失问题解决经验:
1) 判断是不是原因1造成的,可以在每次刷新页面的时候,跟踪bin中某个文件的修改时间.
2) 做Session读写日志,每次读写Session都要记录下来,并且要记录SessionID、Session值、所在页面、当前函数、函数中的第几次Session操作,这样找丢失的原因会方便很多.
3) 如果允许的话,建议使用state server或sql server保存session,这样不容易丢失.
4) 在global.asa中加入代码记录Session的创建时间和结束时间,超时造成的Session丢失是可以在SessionEnd中记录下来的。
<sessionState> 元素设置:
<system.web>
<sessionState mode="Off|InProc|StateServer|SQLServer"
cookieless="true|false"
timeout="number of minutes"
stateConnectionString="tcpip=server:port"
sqlConnectionString="sql connection string"
stateNetworkTimeout="number of seconds"/>
</system.web>
mode |
描述 |
Off |
指示会话状态没有启用。 |
InProc |
默认情况下是InProc,保存20分钟。也就是将Session保存在进程内(IIS5是aspnet_wp.exe,而IIS6是W3wp.exe),这个进程不稳定,在某些事件发生时,进程会重起,所以造成了存储在该进程内的Session丢失。 |
StateServer |
指示在本地或远程服务器上存储会话状态。 ASP.NET 状态服务。默认情况是不启动的。当我们设定mode为StateServer之后,手工将该服务启动。这样,我们就能利用StateServer来存储Session了,除非电脑重启或者StateService崩掉,否则Session是不会丢的(因Session超时被丢弃是正常的) |
SQLServer |
指示在 SQL Server? 上存储会话状态 |
属性 |
描述 |
||
cookieless |
默认不用Cookie来传递会话ID 【<sessionState mode="InProc"cookieless="false" /> cookieless="false" :表示Session不需要Cookie传递;如果修改为cookieless="true":表示Session的ID在Cookie中传递,这样访问时地址栏中会出现多余的文字如:http://localhost:11209/Web/(S(lsua21yjunmcf245wnkogy55))/Index.aspx】。采取这种方式,不管Cookie还是隐藏表单字段都用不着了。所以,即使网页中没有使用表单,也能加入会话。 但是这种方法,应用程序的状态将依赖于 ASP.NET进程, 当IIS进程崩溃或者正常重启时,保存在进程中的状态将丢失。 |
||
stateConnectionString |
指定远程存储会话状态的服务器名称或地址以及端口。端口值默认为42424。当 mode 为 StateServer 值时,该属性是必需的。确保运行ASP.NET 状态服务的服务器是存储会话状态信息的远程服务器。该服务随 ASP.NET 一起安装,默认情况下为%SystemRoot%\Microsoft.NET\Framework\VersionNumber\aspnet_state.exe。
默认值为 "tcpip=127.0.0.1:42424"。 |
||
sqlConnectionString |
为运行 SQL Server 的计算机指定连接字符串。该属性在 mode 属性设置为 SQLServer 值时是必需的
默认值为 "data source=127.0.0.1;Integrated Security=SSPI"。 |
||
allowCustomSqlDatabase |
指定会话状态 SQL 数据库是否可以是自定义数据库(而不是 ASP.NET默认数据库)。如果为 false,则不能指定初始目录或数据库作为sqlConnectionString 属性的值。默认会话状态 SQL 数据库为 ASPState 数据库。有关更多信息,请参见会话状态模式。默认值为 false。 |
||
timeout |
指定在放弃一个会话前该会话可以处于空闲状态的分钟数。对于进程内和状态服务器模式,timeout 属性不能设置为大于 525,601 分钟(1 年)的值。 会话 timeout 配置设置仅适用于 ASP.NET 页。更改会话 timeout 值不会影响 ASP 页的会话超时时间。同样,更改 ASP 页的会话超时时间不会影响 ASP.NET 页的会话超时时间。默认值为 20 分钟。 |
||
stateNetworkTimeout |
当使用 StateServer 模式存储会话状态时,指定在会话被放弃前 Web 服务器和状态服务器之间的 TCP/IP 网络连接处于空闲状态的秒数。默认值是 10。 |
||
cookieName |
指定存储会话标识符的 Cookie 的名称。 此属性是 .NET Framework 2.0版中的新属性。默认值为 "ASP.NET_SessionId"。 |
||
regenerateExpiredSessionId |
指定当客户端指定了过期的会话 ID 时是否重新发出会话 ID。默认情况下,当启用了 regenerateExpiredSessionId 时,仅为 cookieless 模式重新发出会话 ID。 此属性是 .NET Framework 2.0 版中的新属性。默认值为 true。 |
使用 StateServer 模式:
确保在存储会话状态信息的远程服务器上正在运行 ASP.NET 状态服务。此服务随 ASP.NET 一起安装,并且默认位于 <Drive>:\systemroot\Microsoft.NET\Framework\version\aspnet_state.exe。
使用 SQLServer 模式:
在运行 SQL Server 的计算机(将存储会话状态)上运行 InstallSqlState.sql(默认安装在<Drive>:\systemroot\Microsoft.NET\Framework\version 中)。它将使用新的存储过程和 TempDB 数据库中的ASPStateTempApplications 和 ASPStateTempSessions 表创建一个称为 ASPState 的数据库。
不常用属性:
customProvider |
可选的 String 属性。 指定用于存储和检索会话状态数据的自定义会话状态提供程序的名称。该提供程序在 providers 元素中指定。仅当会话状态模式设置为 Custom 值时,才使用该提供程序。有关更多信息,请参见会话状态模式。 此属性是 .NET Framework 2.0 版中的新属性。 默认值为空字符串 ("")。 |
||
partitionResolverType |
可选的 String 属性。 指定在哪里存储会话状态。如果 partitionResolverType 属性中指定了值,则忽略 sqlConnectionString 和 stateConnectionString 属性。PartitionResolverType 属性返回的连接字符串将用于每个请求,为请求的其余部分连接到适当的服务器位置。如果连接字符串无效,ASP.NET 将引发一个异常,该异常与当配置的服务器连接字符串无效时引发的异常相同。该属性用于在 SQL 或状态服务器模式下在多个后端节点上划分会话状态数据。 此属性是 .NET Framework 2.0 版中的新属性。 默认值为空字符串。 |
||
sqlCommandTimeout |
可选的 TimeSpan 属性。 指定使用 SQL Server 会话状态模式的 SQL 命令的持续时间超时(秒)。持续时间超时是 SQL 命令可以处于空闲状态的时间(秒),超过此时间之后,该命令将被取消。 此属性是 .NET Framework 2.0 版中的新属性。 默认值为 0:00:30(30 秒)。 |
||
useHostingIdentity |
可选的 Boolean 属性。 指定会话状态将恢复为宿主标识还是使用客户端模拟。 如果为 true,ASP.NET 将使用下列进程凭据之一来连接会话状态存储区: 宿主进程;对于 Microsoft Internet 信息服务 [IIS] 5 和 5.1 版为ASPNET,对于 Microsoft Windows Server 2003 则为 NETWORK SERVICE。 应用程序模拟标识,当使用了以下配置时使用此凭据: <identity impersonate="true" userName="user" password="pwd" /> 如果为 false,ASP.NET 将使用目前与当前请求的操作系统线程关联的凭据来连接会话状态存储区。对于客户端模拟,ASP.NET 将使用与浏览器协商的安全凭据来连接会话状态存储区。如果为false,ASP.NET 在连接会话状态存储区时不会恢复为进程标识或应用程序模拟标识。有关更多信息,请参见 ASP.NET 模拟。 此属性是 .NET Framework 2.0 版中的新属性。 默认值为 true。
|
ASP.net session丢失的更多相关文章
- ASP.NET Session丢失的情况
正常操作情况下会有ASP.NET Session丢失的情况出现.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成60分钟,不会这么快就超时的. 现在我就把原 ...
- ASP.NET Session丢失的解决方案
正常操作情况下会有ASP.NET Session丢失的情况出现.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成60分钟,不会这么快就超时的.现在我就把原因 ...
- ASP.NET Session丢失问题原因及解决方案
正常操作情况下会有ASP.NET Session丢失的情况出现.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成60分钟,不会这么快就超时的. ASP.NE ...
- asp.net session丢失的解决方法小结
现在我就把原因和解决办法写出来. ASP.NET Session丢失原因: 由于Asp.net程序是默认配置,所以Web.Config文件中关于Session的设定如下: < sessionSt ...
- Session丢失的解决办法小结
最近在做ASP.NET项目时,测试网站老是取不出Session中的值,在网上搜索了一下,找到一些解决方法,记录在这里.最后使用存储在StateServer中的办法解决了问题. SessionState ...
- iis7中session丢失的解决方法小结
这篇文章主要介绍了在windows server 2008系统中,session丢失的解决方法,供大家学习参考 问题描述: Windows Server 2008 +IIS +ASP.net +SQL ...
- Session丢失的原因及解决办法
Asp.net 默认配置下,Session莫名丢失的原因及解决办法: 正常操作情况下Session会无故丢失.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定 ...
- ASP.NET 状态服务 及 session丢失问题解决方案总结
ASP.NET2.0系统时,在程序中做删除或创建文件操作时,出现session丢失问题.采用了如下方法:1.asp.net Session的实现:asp.net的Session是基于HttpModul ...
- asp.net 修改/删除站内目录操作后会导致Session丢失
http://www.jb51.net/article/21770.htm http://blog.chinaunix.net/uid-7425507-id-134216.html 在Web项目中使用 ...
随机推荐
- 洛谷—— P2668 斗地主
https://www.luogu.org/problem/show?pid=2668 题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54 ...
- CF909A Generate Login
CF909A Generate Login 题意翻译 给定两个用空格分隔的字符串,分别取两字符串的任意非空前缀,将两前缀合并为一个新的字符串,求可行字典序最小的字符串. 题目描述 The prefer ...
- Libevent学习笔记
学习: /Users/baidu/Documents/Data/Interview/服务器-检索端/libevent参考手册(中文版).pdf 讲的不好.翻译的..
- HDU 3886
一开始又往打表想了....不过,打表确实不好处理,转DFS. DFS有几个要注意的问题,1.对于枚举以零开始的数.我纠结了很久,最终学习别人的方法,设一个BOOL,并且假设最高一位有零,很方便.2.当 ...
- python爬虫系列:Scrapy安装与使用
这篇博文主要写Scrapy框架的安装与使用 Scrapy框架安装 命令行进入C:\Anaconda2\Scripts目录,运行:conda install Scrapy 创建Scrapy项目 1)进入 ...
- HDU 1042.N!【高精度乘法】【8月24】
N! Problem Description Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N! Input One N ...
- java 顺序 读写 Properties 配置文件 支持中文 不乱码
java 顺序 读写 Properties 配置文件 ,java默认提供的Properties API 继承hashmap ,不是顺序读写的. 特从网上查资料,顺序读写的代码,如下, import j ...
- linux:共享内存
#include <sys/ipc.h> #include <sys/shm.h> #include <string.h> #include <stdio.h ...
- [Golang] 从零開始写Socket Server(3): 对长、短连接的处理策略(模拟心跳)
通过前两章,我们成功是写出了一套凑合能用的Server和Client,并在二者之间实现了通过协议交流.这么一来,一个简易的socket通讯框架已经初具雏形了,那么我们接下来做的.就是想办法让这个框架更 ...
- Hessian Servlet实例
Servlet实例 业务场景 在下面的例子中我会发布一个简单的输出字符串的方法,然后在客户端调用并输出结果. 服务器端 环境搭建 在服务端,我们需要引入hessian和servlet的包.编写服务.配 ...