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