ASP.NET 使用mode=”InProc”方式保存Session老是丢失,无奈改成StateServer 模式。

时间:2022-05-23 01:35:17

http://blog.csdn.net/fox123871/article/details/8165431

session是工作在你的应用程序进程中的。asp.net进程、iis往往会在20分钟之后重启相关的应用程序,缓冲池满了(例如100个之 后)也会重启,各种进程保护措施都会随时重新启动,因此InProc方式丢失session是很正常的事。csdn上明确告诉了这种模式只能保存“易失 的、暂时的 ”变量,这是cache没有之前的一种解决方案。而长期保持的数据就要保存在外部数据源中。状态服务器就是一种进程外的数据源。

StateServer 模式的实质是,把Session 存放在一个单独的进程里,此进程独立于 aspnet_wp.exe 或 w3wp.exe 。启用此服务后,在“任务管理器”中可以看到一个名为 aspnet_state.exe 的进程,下面开始说明一下设置的具体步骤:

1、 修改注册表(关键步骤,如下图)

运行 regedit → 打开注册表 →
找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state
\Parameters 节点 → 将 AllowRemoteConnection 的键值设置成“1”(1 为允许远程电脑的连接,0 代表禁止)→
设置 Port (端口号)

注意事项:

a)、若ASP.NET State Service 正在运行,修改注册表内容后,则需要重新启动该服务

b)、注意端口号的键值是以十六进制储存的,可以使用十进制进行修改,42424 是默认的端口

c)、AllowRemoteConnection
的键值设置成“1”后,意味着允许远程电脑的连接,也就是说只要知道你的服务端口,就可享用你的ASP.NET State Service,即把
Session 存放在你的电脑进程内,因此请大家慎用;键值为“0”时,仅有stateConnectionString
为“tcpip=localhost: 42424”与“tcpip=127.0.0.1:42424”的情况,方可使用ASP.NET State
Service

2、 开启 ASP.NET State Service

右键点击“我的电脑”→ 管理 → 服务与应用程序 → 服务 → 双击“ASP.NET State Service” → 启动(可设为“自动”)

说明:只要安装了 .Net Framework ,都拥有此服务。

3、 更改 Web.config

打开 Web.config → 找到 <sessionState> 节点内容

<sessionState

mode=”InProc”

stateConnectionString=”tcpip=127.0.0.1:42424″

sqlConnectionString=”data source=127.0.0.1;Trusted_Connection=yes”

cookieless=”false”

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
【<sessionStatemode="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。

< xmlnamespace prefix ="v" ns ="urn:schemas-microsoft-com:vml" />注意

若要在使用 StateServer 模式时提高您的应用程序的安全性,请使用受保护的配置来加密配置的
<sessionState> 节,以帮助保护 stateConnectionString
值。

默认值为 "tcpip=127.0.0.1:42424"。

sqlConnectionString

为运行 SQL Server 的计算机指定连接字符串。该属性在 mode
属性设置为 SQLServer 值时是必需的

注意

若要在使用 SQLServer 模式时提高您的应用程序的安全性,请使用受保护的配置来加密配置的
sessionState 节,以帮助保护 sqlConnectionString
值。

默认值为 "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。

注意

在 .NET Framework 1.1 版中,如果 mode
属性设置为 SQLServer,并且客户端模拟有效,则 ASP.NET
使用来自 ASP.NET 客户端模拟的客户端凭据连接到运行 SQL Server
的计算机。

timeout=”20″ />

→ 将其改为以下内容

<sessionState mode=”StateServer” stateConnectionString=”tcpip=192.168.0.2:42424″ timeout=”20″ />

注意事项:
1、timeout=”20″为Session 20分钟超时

2、IP 地址(可以是远程计算机 IP、计算机名称、域名)与端口号,端口号需与ASP.NET State Service 的服