【问题标题】:Session expiring after 20 minutes: Whether idle or not会话在 20 分钟后过期:是否空闲
【发布时间】:2011-04-30 18:24:29
【问题描述】:

我在用户填写申请表时丢失会话数据时遇到了一些麻烦。看来他们正在通过申请表部分丢失会话状态。 (ASP.NET 4.0 WebForms 项目,IIS 6.0)

会话存储在状态服务器中的进程外,因此它不是配置更改、应用程序域回收等 AFAIK。

<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="20" />

我正在使用表单身份验证,滑动到期工作正常,您可以从下面的日志中看到 - 您可以看到票证到期时间正确并按预期延长。

<authentication mode="Forms">
   <forms loginUrl="~/Login.aspx" />
</authentication>

我启用了一些自定义日志记录来尝试追踪这一点。在global.asax 中的每一次Session_Start 触发时,我都会记录一些内容,并且每次有人加载申请表或单击“下一步”以在浏览应用程序表单时在部分之间(在多视图中)移动时,我也会记录一些内容。

以下是人们失去会话状态的两个示例。日志以日志条目的日期/时间开始,然后是一些措辞。括号中的第二个日期/时间(在措辞之后)是 FormsAuthentication cookie 的到期日期/时间,源自 CType(ctx.User.Identity, FormsIdentity).Ticket.Expiration.ToString

日志还会记录用户的 IP 地址和会话 ID。在将它们粘贴到此处之前,我已将它们删除,我可以确认所有日志条目的 IP 地址和会话 ID 相同。

示例 1:

**[26/10/2010 13:07] 会议开始 []** [26/10/2010 13:11] 申请表第一页_Load [26/10/2010 13:31:19] [26/10/2010 13:13] 下一次点击应用程序窗体,当前索引为 1 (vwSection1) [26/10/2010 13:31:19] [26/10/2010 13:14] 下一次点击应用程序窗体,当前索引为 2 (vwSection2) [26/10/2010 13:31:19] [26/10/2010 13:15] 下一次点击应用程序窗体,当前索引为 3 (vwSection3) [26/10/2010 13:31:19] [26/10/2010 13:20] 下一次点击应用程序窗体,当前索引为 5 (vwSection4) [26/10/2010 13:31:19] [26/10/2010 13:20] 下一次点击应用程序窗体,当前索引为 6 (vwSection5) [26/10/2010 13:31:19] [26/10/2010 13:20] 下一次点击应用程序窗体,当前索引为 7 (vwMonitoring) [26/10/2010 13:31:19] [26/10/2010 13:21] 下一次点击应用程序窗体,当前索引为 8 (vwInformation) [26/10/2010 13:31:19] [26/10/2010 13:22] 申请表第一页_Load [26/10/2010 13:41:22] [26/10/2010 13:25] 下一次点击应用程序窗体,当前索引为 1 (vwSection1) [26/10/2010 13:41:22] [26/10/2010 13:26] 下一次点击应用程序窗体,当前索引为 2 (vwSection2) [26/10/2010 13:41:22] [26/10/2010 13:26] 下一次点击应用程序窗体,当前索引为 3 (vwSection3) [26/10/2010 13:41:22] [26/10/2010 13:28] 下一次点击应用程序窗体,当前索引为 5 (vwSection4) [26/10/2010 13:41:22] [26/10/2010 13:28] 下一次点击应用程序窗体,当前索引为 6 (vwSection5) [26/10/2010 13:41:22] [26/10/2010 13:28] 下一次点击应用程序窗体,当前索引为 7 (vwMonitoring) [26/10/2010 13:41:22] [26/10/2010 13:28] 下一次点击应用程序窗体,当前索引为 8 (vwInformation) [26/10/2010 13:41:22] **[26/10/2010 13:28] 会议开始 [26/10/2010 13:41:22]** [26/10/2010 13:31] 申请表第一页_Load [26/10/2010 13:51:24] [26/10/2010 13:31] 下一次点击应用程序窗体,当前索引为 1 (vwSection1) [26/10/2010 13:51:24] [26/10/2010 13:32] 下一次点击应用程序窗体,当前索引为 2 (vwSection2) [26/10/2010 13:51:24] [26/10/2010 13:32] 下一次点击应用程序窗体,当前索引为 3 (vwSection3) [26/10/2010 13:51:24] [26/10/2010 13:32] 下一次点击应用程序窗体,当前索引为 5 (vwSection4) [26/10/2010 13:51:24] [26/10/2010 13:32] 下一次点击应用程序窗体,当前索引为 6 (vwSection5) [26/10/2010 13:51:24] [26/10/2010 13:32] 下一次点击应用程序窗体,当前索引为 7 (vwMonitoring) [26/10/2010 13:51:24] [26/10/2010 13:32] 下一次点击应用程序窗体,当前索引为 8 (vwInformation) [26/10/2010 13:51:24]

示例 2:

**[24/10/2010 17:44] 会议开始 []** [24/10/2010 17:50] 申请表第一页加载 [24/10/2010 18:10:13] [24/10/2010 18:00] 应用窗体下一次点击,当前索引为 1 (vwSection1) [24/10/2010 18:20:40] **[24/10/2010 18:07] 会议开始 [24/10/2010 18:20:40]** [24/10/2010 18:08] 下一次点击应用程序窗体,当前索引为 2 (vwSection2) [24/10/2010 18:20:40] [24/10/2010 18:10] 下一次点击应用程序窗体,当前索引为 2 (vwSection2) [24/10/2010 18:20:40] [24/10/2010 18:10] 下一次点击应用程序窗体,当前索引为 1 (vwSection1) [24/10/2010 18:30:42] [24/10/2010 18:10] 下一次点击应用程序窗体,当前索引为 1 (vwSection1) [24/10/2010 18:30:52] [24/10/2010 18:10] 下一次点击应用程序窗体,当前索引为 1 (vwSection1) [24/10/2010 18:30:58] [24/10/2010 18:12] 申请表第一页_Load [24/10/2010 18:31:35] [24/10/2010 18:12] 下一次点击应用程序窗体,当前索引为 1 (vwSection1) [24/10/2010 18:31:35] [24/10/2010 18:13] 下一次点击应用程序窗体,当前索引为 2 (vwSection2) [24/10/2010 18:31:35] [24/10/2010 18:13] 下一次点击应用程序窗体,当前索引为 2 (vwSection2) [24/10/2010 18:31:35] [24/10/2010 18:16] 下一次点击应用程序窗体,当前索引为 3 (vwSection3) [24/10/2010 18:31:35] [24/10/2010 18:16] 下一次点击应用程序窗体,当前索引为 5 (vwSection4) [24/10/2010 18:31:35] [24/10/2010 18:17] 下一次点击应用窗体,当前索引为 6 (vwSection5) [24/10/2010 18:31:35] [24/10/2010 18:18] 下一次点击应用程序窗体,当前索引为 7 (vwMonitoring) [24/10/2010 18:31:35] [24/10/2010 18:18] 下一次点击应用程序窗体,当前索引为 8 (vwInformation) [24/10/2010 18:31:35]

您可以在第一个示例中看到会话最初开始于 13:07,但也开始于 13:28。

您可以在第二个示例中看到会话最初在 17:44 开始,并在 18:07 重新启动。

我知道这些时间是会话开始后 20 分钟。但是会话不是空闲的。您可以看到它没有空闲,因为日志的其余部分。在应用程序表单中单击“下一步”会使某个对象脱离会话状态

Dim m As Member = StateManager.CurrentMember

然后获取/设置“m”的属性。

因此,在我看来,即使用户没有空闲并访问他们的会话变量,他们在开始后正好 20 分钟仍会丢失会话。请注意,在我的基本页面(所有页面都继承自,基本页面继承 System.Web.UI.Page)中,我现在已经开始将当前毫秒写入会话状态,因此我不断写入会话。

用户正在失去他们的会话状态,因为 StateManager.CurrentMember(只是 HttpContext.Current.Session("CurrentMember"))返回 null。当我尝试将其附加到实体框架数据上下文时,这会给出一个未处理的异常 - 因此用户会看到我的通用错误处理页面。

任何想法表示赞赏。

【问题讨论】:

  • 嗨 bgs264,您能否连同现有日志一起写下 Session_Start 事件期间的 Session.IsNewSession 值是什么?我对它在会话重启期间的价值感兴趣。我怀疑会话在某个地方突然结束了。
  • 会话是否有可能只在“申请表第一个 Page_Load”而不是按钮点击时更新?
  • 调试时是否会在本地主机上发生这种情况?这不是需要粘性会话的负载平衡环境吗?您是否将大型对象置于会话状态并达到内存限制?应用池回收是否触发应用重启?

标签: asp.net iis-6 session-state asp.net-4.0 session-timeout


【解决方案1】:

您提到您正在使用 FormsAuthentication。您是否将滑动过期属性设置为 true?

http://msdn.microsoft.com/en-us/library/1d3t3c61(v=VS.100).aspx

【讨论】:

  • 感谢您的回答。未指定滑动到期,因此它已变为默认值 true。用户没有被注销并被要求再次登录,他们只是丢失了会话数据。您可以从日志中看到滑动到期工作正常 - 查看显示票证到期时间的行上的最后一个时间戳 - 这正在适当地延长,但 session_start 仍然会再次触发。将更新我的 Q。
【解决方案2】:

我唯一一次看到这种情况发生是在代码中引用了 localhost 时。

虽然您说它在某个其他服务器中,但我想刷新 AppPool 会丢失对会话信息的引用,并因此创建另一个。 尝试此操作的一种方法是转到 IIS 并进行配置,池的刷新会发生更多错误,从而导致可能永远不会刷新的情况,然后您可能会找到所需的内容。试试看,然后告诉我。

【讨论】:

  • 感谢您的回复,我确信 IIS 设置都是正确的,并且工作进程仅设置为每天早上 5 点回收,而不是每 XXX 分钟回收一次。应用程序池设置为空闲 20 分钟或更长时间后回收;但由于它不是空闲的,它不应该被回收,除非 IIS 需要重新安装或其他东西。我已经通过解决方法解决了这个问题,删除了会话变量并改为进行数据库往返。
  • 应用程序池被回收的原因还有很多,其中之一就是每当您的应用程序或同一池中的任何其他应用程序抛出错误时,它都会添加一个计数器,然后有一个阈值,当达到应用程序池回收时。关键是它不需要是你的应用程序。
  • 想到的另一个原因是,如果在网站运行时更改网站的结构,即删除文件夹,应用程序池会被回收。
【解决方案3】:

默认 IIS 应用程序池超时为 20 分钟。这可能会有所帮助:MSDN

【讨论】:

  • 感谢您的回复,您的链接显示“空闲 20 分钟后关闭工作进程” - 默认应该没问题 - 工作进程没有被关闭,否则我会看到生命周期事件健康监控电子邮件。可能 IIS 已损坏,需要重新安装。我解决了一个解决方法来删除会话变量并根据视图状态变量进行数据库往返,所以现在可以了,感谢您的回复。
猜你喜欢
  • 2015-02-21
  • 1970-01-01
  • 1970-01-01
  • 2020-04-06
  • 1970-01-01
  • 2011-04-15
  • 1970-01-01
  • 2014-04-17
  • 2017-05-17
相关资源
最近更新 更多