【发布时间】:2011-01-09 21:32:07
【问题描述】:
您好,您对这个问题有什么看法?
我们在HttpSession 中确实有太多信息,因为需要计算大量信息,并且最终需要在请求之间存储一些大型对象图。
使用memcache之类的缓存是否合适?还是和JVM增加内存一样?
担心在请求之间将其存储在数据库中。如果我们得到你会用什么 OutOfMemory 错误?
谢谢。
【问题讨论】:
您好,您对这个问题有什么看法?
我们在HttpSession 中确实有太多信息,因为需要计算大量信息,并且最终需要在请求之间存储一些大型对象图。
使用memcache之类的缓存是否合适?还是和JVM增加内存一样?
担心在请求之间将其存储在数据库中。如果我们得到你会用什么 OutOfMemory 错误?
谢谢。
【问题讨论】:
HttpSession 确实不能很好地扩展,但这主要与 集群 有关。这是一种便利,但在某些时候,是的,您最好使用 memcache、Terracotta 或 EHCache 之类的东西在请求之间(或用户之间)持久化数据。
【讨论】:
我认为真正的关键是数据的生命周期。
想想HttpSession的这两个特点:
如果您有集群需求,数据库会处理它。但要注意,你不能在内存中缓存任何东西。
存储在数据库中的寿命更长(在会话之间持续存在,甚至在重新启动之间持续存在!),所以这个问题甚至是值得的(除非你用内存问题换取性能问题)。
我认为对于预期寿命不会持久的数据,这是错误的方法......
如果数据只对一个请求有用,那么它通常存储在 HttpRequest 中,很好。
但是如果它用于几个请求(一个屏幕内的交互,或者像助手这样的屏幕序列内的交互..),HttpRequest 太短而无法存储它,但 HttpSession 太长。数据需要定期清理。
并且HttpSession 中的许多内存问题都与此类暂时但未清理的数据有关(完全忘记,或在出现异常时未清理,或当用户不尊重常规流程:点击Back,使用以前的书签,点击不同的菜单或其他)。
为了完全避免这种清理工作(并避免出现问题时出现 OutOfMemory 的风险),您可以将信息存储在具有正确生命周期的数据结构中。由于容器不提供此功能(无论如何它与应用程序相关),您需要使用缓存库自己实现此功能(如提到的那些;我们使用 EhCache)。
这个想法是您有一个技术代码(与一个功能页面无关,但在全局范围内实现,例如使用 ServletFilter ...)确保在不再需要对象后始终进行清理。
您可以使用以下一种(或根据需要)清除缓存的策略来设计此缓存。每项政策都与功能生命周期相关:
实现思路:每个请求都必须携带自己的screenId,负责清缓存的技术代码检测当前HttpSession id与缓存中的不匹配时。然后它会清除或重置缓存中的该项。
实现:和之前一样,每个请求都需要携带模块id...
实现:缓存库原生支持这个限制因素,还有更多......
对于仅在几分钟内有效的数据,缓存库可以原生配置为在延迟后丢弃它...
...更多,请参阅缓存库配置以了解其他想法。
注意:每个缓存都可以是应用程序范围的,或特定于用户、HttpSession id、Company id 或其他功能值...
【讨论】: