【问题标题】:Losing Session State丢失会话状态
【发布时间】:2011-03-31 18:22:18
【问题描述】:

我有一个 ASP.net 应用程序,其中用户无法成功完成某些操作,我假设原因只能与丢失他们的会话有关(这是我维护他们当前用户信息的地方,并且如何判断是否登录)

我不知道他们为什么会失去他们的会话,所以我的第一个问题是:

什么(通常)会导致用户在 ASP.net 中丢失会话?

而且由于我不知道用户何时失去他们的会话并且自己无法重现它:

我如何跟踪我的用户何时失去他们的会话

以下是我的 sessionState 配置供参考

<sessionState
           mode="InProc"
           cookieless="false"
           cookieName="My.Site.Com"
           timeout="480"/>

【问题讨论】:

  • 你可能想太多了。您说您“假设”会话正在丢失。这很可能是一场野鹅追逐。也许您可能会更好地分析您收到的异常并将其考虑在内。其他可能性包括使用网络场或集群的问题。由于会话模式为“InProc”,如果连接更改您身上的服务器,会话状态将丢失。
  • 我知道我没有使用网络场,但我确定我在虚拟机上。诚然,我只是假设,但我大约 80% 确定它是会话状态,至少我想继续假设它是一个问题,直到我可以排除它。
  • 对我来说,将机器密钥添加到我的 web.config 是有效的。我在共享主机上托管,此链接有助于创建一个本地然后发布它。 link

标签: asp.net iis session


【解决方案1】:

许多事情都可能导致会话状态神秘地消失。

  1. 您的 sessionState 超时已过期
  2. 您更新了您的 web.config 或其他导致 AppDomain 回收的文件类型
  3. IIS 中的 AppPool 回收
  4. 您使用大量文件更新您的站点,ASP.NET 会主动销毁您的 AppDomain 以重新编译和保留内存。

-

如果您使用的是 IIS 7 或 7.5,请注意以下几点:

  1. 默认情况下,IIS 将 AppPools 设置为在一段时间不活动后自行关闭。
  2. 默认情况下,IIS 将 AppPools 设置为每 1740 分钟回收一次(显然取决于您的根配置,但这是默认设置)
  3. 在 IIS 中,检查 AppPool 的“高级设置”。其中有一个名为“空闲超时”的属性。将其设置为零或高于默认值 (20)。
  4. 在 IIS 中,检查 AppPool 的“回收”设置。您可以在此处启用或禁用您的 AppPool 进行回收。向导的第二页是一种将每种类型的 AppPool 关闭记录到事件日志的方法。

如果您使用的是 IIS 6,则应用相同的设置(大部分情况下使用不同的获取方式),但是让它们记录回收更麻烦。以下是让 IIS 6 记录 AppPool 回收事件的方法的链接:

http://web.archive.org/web/20100803114054/http://surrealization.com/sample-code/getnotifiedwhenapppoolrecycles/

-

如果您要更新 Web 应用程序上的文件,您应该预计所有会话都会丢失。这就是野兽的本性。但是,您可能不会期望它会发生多次。如果您更新 15 个或更多文件(aspx、dll 等),您可能会在一段时间内多次重新启动,因为访问该站点的用户会重新编译这些页面。查看这两个链接:

http://support.microsoft.com/kb/319947

http://msdn.microsoft.com/en-us/library/system.web.configuration.compilationsection.numrecompilesbeforeapprestart.aspx

将 numCompilesBeforeAppRestart 设置为更高的数字(或手动反弹您的 AppPool)将消除此问题。

-

您始终可以处理 Application_SessionStart 和 Application_SessionEnd 以在会话创建或结束时收到通知。 HttpSessionState 类还有一个IsNewSession 属性,您可以检查任何页面请求以确定是否为活动用户创建了新会话。

-

最后,如果在您的情况下可能的话,我已经成功使用了SQL Server session mode。如果您在其中存储大量数据(每个请求从 SQL Server 加载并保存全部数据),则不建议这样做,如果您将自定义对象放入其中可能会很痛苦(因为它们必须是可序列化的),但它在我无法将我的 AppPool 配置为不回收几个小时的共享托管方案中帮助了我。就我而言,我存储了有限的信息,并且对性能没有不利影响。除此之外,现有用户将默认重用其 SessionID,而我的用户从未注意到他们的内存中 Session 被 AppPool 回收丢弃的事实,因为他们的所有状态都存储在 SQL Server 中。

【讨论】:

  • 哇...非常详尽的清单,谢谢!您列出了服务器端可能发生的所有事情,是否有任何事情会阻碍 IIS 识别请求并将其与propper session 匹配的能力?
  • 是的,但可能性要小得多。其他人在这里提到代理可能会丢弃会话 cookie,尽管任何现代代理都不太可能这样做(因为所有现代 Web 开发环境都使用会话 cookie)。我最近在一个 Web 应用程序上经历了几次 - 首先是 AppPool 回收,然后是页面更新(由更新中的 > 15 个页面引起)。
  • 如何在服务器(不是我的本地电脑)上配置 IIS?
  • 刚刚在一个较旧的 asp.net 应用程序上工作,它是“20 分钟默认值”。
  • 即使是当前的 IIS 也默认为 20 分钟。 @JonH
【解决方案2】:

我在 ASP.NET 4.0 中遇到了这样一种情况,即我的会话将在每个页面请求时重置(并且我的 SESSION_START 代码将在每个页面请求上运行)。并非每个会话的每个用户都会发生这种情况,但它通常会发生,并且当它发生时,它会发生在每个页面请求上。

我的 web.config sessionState 标记与上面提到的设置相同。

cookieless="false"

当我把它改成下面...

cookieless="UseCookies"

...问题似乎消失了。显然 true|false 是 ASP.NET 1 中的旧选项。从 ASP.Net 2.0 开始,枚举选项开始可用。我猜这些选项已被弃用。 “false”值过去从未出现过问题——我只在 ASP.NET 4.0 上注意到过。我不知道 4.0 中是否发生了一些变化,不再正确支持它。

另外,我不久前才发现这一点。由于问题之前是间歇性的,我想我仍然可以遇到它,但到目前为止它正在使用这个新设置。

【讨论】:

    【解决方案3】:

    您的会话丢失了,因为......

    我发现了会话丢失的情况 - 在 asp.net 页面中,对于金额文本框字段具有无效字符,然后为其他目的检索会话变量。通过转换发布无效数字解析后。 ToInt32 或 double 引发第一次机会异常,但该行未显示错误,取而代之的是,由于未处理的异常,Session 为空,在会话检索时显示错误,从而欺骗调试...

    提示:测试您的系统以使其失败-破坏性..在不相关的场景中输入足够的垃圾,例如:在搜索结果显示后在搜索条件中输入垃圾并转到搜索结果的详细信息...,您将能够重现此本地代码库上的机器也...:)

    希望对你有帮助,技术人员

    【讨论】:

    • +1 。非常有趣。我们有完全相同的问题。写入文本文件时出现未处理的错误导致会话被清除!在写入文本文件模块中,没有任何代码可以触及会话!
    【解决方案4】:

    在我的情况下,将 AppPool->AdvancedSettings->Maximum Worker Processes 设置为 1 有帮助。

    【讨论】:

      【解决方案5】:

      您可以在 Session_Start 和 Application_Start 的 Global.asax 中添加一些日志记录,以跟踪用户的 Session 和整个应用程序的情况。

      另外,请注意您在 Web Farm 模式下运行(应用程序池中定义了多个 IIS 线程)或负载平衡,因为用户最终可能会访问没有相同内存的不同服务器。如果是这种情况,您可以将会话模式切换到 SQL Server。

      【讨论】:

      • Web Farm 不会是应用程序池的多个工作进程。那将是一个网络花园。一个网络农场将跨越多个服务器。
      【解决方案6】:

      我只是丢失了不是字符串或整数而是数据行的会话。 将数据放入可序列化的对象并将其保存到会话中对我有用。

      【讨论】:

        【解决方案7】:

        通过 Ajax 检索内容时在 IIS 8 上出现问题。问题是 MaximumWorkerProcesses 设置为 2 并且 Javascript 打开了 17 个并发请求。这超出了 AppPool 的处理能力,因此打开了一个新池(没有 auth-data)。

        解决方案是将MaximumWorkerProcesses 中的0 更改为0

        【讨论】:

          【解决方案8】:

          不知道这是否与您的问题有关,但 Windows 2008 Server R2 或 SP2 已更改其 IIS 设置,这会导致会话持久性问题。默认情况下,它为 HTTP 和 HTTPS 管理单独的会话变量。在 HTTPS 中设置变量时,这些变量将仅在 HTTPS 页面上可用。

          为了解决这个问题,有 IIS 设置。在 IIS 管理器中,打开 ASP 属性,展开 Session Properties,然后更改 安全连接上的新 ID 改为 False

          【讨论】:

            【解决方案9】:

            我因失去会话而遇到同样的问题。每次,每一个页面重新加载,我的会话清除,并通过新的重新加载任何页面,我的会话返回有效值...

            我通过在 iis 中将 MaximumWorkerProcesses 从 0 更改为 1 来修复它

            【讨论】:

              【解决方案10】:

              我在这个问题上苦苦挣扎了 14 天。

              这对我有帮助:

              1. 在应用程序池 > 高级设置中检查您的回收选项。关闭所有选项,使其不会自行回收。
              2. 检查web.config 文件中executionTimeout 属性在httpRuntime 下并增加其值。
              3. 检查web.config 文件中timeout 属性在sessionState 下,并增加其值(我将其设置为300 分钟)。
              4. 转到服务器的事件日志并检查应用程序日志中可能导致工作进程崩溃的未处理异常。在您的代码中修复它们或使用trycatch 来消除此崩溃。
              5. 尝试将最大工作进程的值从 0 更改为 1 或其他方式,这也可能解决此问题。

              【讨论】:

                猜你喜欢
                • 2021-03-03
                • 2012-02-01
                • 2019-07-18
                • 2016-10-21
                • 1970-01-01
                • 2010-09-24
                • 1970-01-01
                • 2011-10-08
                • 2012-04-17
                相关资源
                最近更新 更多