如何在Web服务器端实现会话超时?

时间:2010-04-04 15:32:35

标签: session

我看到了一个以这种方式实现内存会话的Web框架。会话对象被添加到Cache with timeout。当时间结束时,会话将自动从缓存中删除。为了保护竞争条件,每个请求都应获取对给定会话对象的锁定以继续。每个请求都会 “触摸” 缓存中的会话以刷新超时。

一切都很好,直到发现这种情况。比如说,一次操作需要很长时间,比超时时间长。另一个请求来到并等待会话锁定,该锁定当前由长时间请求保持。最后,长时间请求结束,它释放锁定。但是,由于它已经比超时花费更长的时间,因此会话对象已从Cache中删除。这是显而易见的,因为持有锁的唯一请求没有机会“ 触摸 ”缓存中的会话对象。第二个请求获取锁定但无法检索过期的Session对象。糟糕...

要解决此问题,第二个请求必须重新创建Session对象。但是,这就像从坟墓中挖出一具埋藏的尸体,并试图让它恢复生机。它会导致错误的代码。

我想知道在会话中实现超时的最佳方法是什么来处理这种情况。我知道当前平台必须具有良好的会话机制。我只想知道引擎盖下的情况。

2 个答案:

答案 0 :(得分:2)

Hi Morgan Cheng(香港人?),

当您的长时间请求完成时, touch - 会话对象可以解决您的问题吗?

让我们通过一个例子来讨论解决方案。当请求到达时,您触摸会话并将其延长5分钟。请求结束时,您还可以触摸会话并将其延长1分钟,然后再释放锁定。如果“结束请求+一分钟”的结果早于“开始请求+ 5分钟”,则使用后者作为超时;否则使用前者。 (当然,5分钟和1分钟可能是你喜欢的任何价值。)

我想知道你正在使用什么样的“缓存”。根据您的描述,似乎缓存会“自动”销毁会话对象。如果是这种情况,那么当请求到达时,您可以 touch 具有非常大的超时值的会话,例如一天。请求结束后,您重新touch 使用合理的值,例如 5分钟。或者, smarter ,使用值(5 minutes - request_time > 1 minute) ? (5 minutes - request_time) : 1 minute),其中request_time是请求所花费的时间。

希望这有帮助。

Asuka Kenji

(来自香港)

答案 1 :(得分:1)

首先,我不会在Cache中做任何与Session相关的事情。如果会话需要自杀,如果没有使用这么多分钟,我会在Session中跟踪所有这些。其次,我倾向于使用一个包装类来访问Session,这样当访问或触摸任何值时,标记(它本身可以存储在Session中)来确定它是否应该自杀以及代码可以封装“杀死会话”。