【问题标题】:too much information in HttpSessionHttpSession 中的信息太多
【发布时间】:2011-01-09 21:32:07
【问题描述】:

您好,您对这个问题有什么看法?

我们在HttpSession 中确实有太多信息,因为需要计算大量信息,并且最终需要在请求之间存储一些大型对象图。

使用memcache之类的缓存是否合适?还是和JVM增加内存一样?

担心在请求之间将其存储在数据库中。如果我们得到你会用什么 OutOfMemory 错误?

谢谢。

【问题讨论】:

    标签: java session servlets


    【解决方案1】:

    HttpSession 确实不能很好地扩展,但这主要与 集群 有关。这是一种便利,但在某些时候,是的,您最好使用 memcache、Terracotta 或 EHCache 之类的东西在请求之间(或用户之间)持久化数据。

    【讨论】:

      【解决方案2】:

      我认为真正的关键是数据的生命周期。


      想想HttpSession的这两个特点:

      • 在集群中,容器负责复制 HttpSession。这很好(您不必自己管理),但如果这会导致过多的交换,则可能会在性能方面造成危险...如果您的应用程序不是集群的,请忘记这一点。
      • HttpSession 的生命周期 可以是几分钟或几小时,即用户保持活动状态。这对于具有该生命周期的信息(连接信息、偏好、授权......)来说是完美的。但它不适用于从一屏到下一屏有用的数据,我们称之为瞬态+数据。

      如果您有集群需求,数据库会处理它。但要注意,你不能在内存中缓存任何东西。

      存储在数据库中的寿命更长(在会话之间持续存在,甚至在重新启动之间持续存在!),所以这个问题甚至是值得的(除非你用内存问题换取性能问题)。

      我认为对于预期寿命不会持久的数据,这是错误的方法......


      瞬态数据

      如果数据只对一个请求有用,那么它通常存储在 HttpRequest 中,很好。

      但是如果它用于几个请求(一个屏幕内的交互,或者像助手这样的屏幕序列内的交互..),HttpRequest 太短而无法存储它,但 HttpSession 太长。数据需要定期清理。

      并且HttpSession 中的许多内存问题都与此类暂时但未清理的数据有关(完全忘记,或在出现异常时未清理,或当用户不尊重常规流程:点击Back,使用以前的书签,点击不同的菜单或其他)。

      缓存库具有正确的生命周期

      为了完全避免这种清理工作(并避免出现问题时出现 OutOfMemory 的风险),您可以将信息存储在具有正确生命周期的数据结构中。由于容器不提供此功能(无论如何它与应用程序相关),您需要使用缓存库自己实现此功能(如提到的那些;我们使用 EhCache)。

      这个想法是您有一个技术代码(与一个功能页面无关,但在全局范围内实现,例如使用 ServletFilter ...)确保在不再需要对象后始终进行清理。

      您可以使用以下一种(或根据需要)清除缓存的策略来设计此缓存。每项政策都与功能生命周期相关:

      • 对于仅与一个屏幕相关的数据(但有多个请求:重新加载屏幕、Ajax 请求......),缓存一次只能存储一个屏幕的数据(对于每个会话),称之为“currentScreenCache” .这保证了,如果用户转到另一个屏幕(即使以非托管方式),新屏幕将覆盖“currentScreenCache”信息,并且可以对以前的信息进行垃圾收集。

      实现思路:每个请求都必须携带自己的screenId,负责清缓存的技术代码检测当前HttpSession id与缓存中的不匹配时。然后它会清除或重置缓存中的该项。

      • 对于仅在一系列连接屏幕中使用的数据(称为功能模块),同样适用于模块级别。

      实现:和之前一样,每个请求都需要携带模块id...

      • 对于重新计算成本高昂的数据,可以将缓存库配置为存储最后 X 个计算的数据(之前的数据被认为不太可能在不久的将来有用)。在典型用法中,会定期要求相同的请求,因此您有很多缓存命中。在密集使用时,会达到 X 限制并且内存不会膨胀,从而防止出现 OutOfMemory 错误(以下次重新计算为代价)。

      实现:缓存库原生支持这个限制因素,还有更多......

      • 对于仅在几分钟内有效的数据,缓存库可以原生配置为在延迟后丢弃它...

      • ...更多,请参阅缓存库配置以了解其他想法。

      注意:每个缓存都可以是应用程序范围的,或特定于用户、HttpSession id、Company id 或其他功能值...

      【讨论】:

      • 如果这个日期有效并且可能在 HttpSession 的整个生命周期中都需要,那么我们应该使用 HttpSession 否则缓存?
      • 错误我想写如果这个数据:)
      • @blefesd 是的,这个想法是将数据存储在具有正确寿命的地方。而且 HttpSession 的生命周期很长... :-)
      猜你喜欢
      • 2021-12-22
      • 1970-01-01
      • 2012-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-22
      • 1970-01-01
      相关资源
      最近更新 更多