HttpSession 中的信息过多 [英] too much information in HttpSession

查看:75
本文介绍了HttpSession 中的信息过多的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,您如何看待这个问题?

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

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

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

谢谢.

解决方案

我认为真正的重点是数据的生命周期.


想想HttpSession的这两个特点:

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

如果您有集群需求,数据库会处理它.但请注意,您将无法在内存中缓存任何内容.

存储在数据库中的生命周期更长(在会话之间,甚至在重新启动之间保持不变!),所以这个问题甚至值得(除非你用内存问题换取性能问题).

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


瞬态数据

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

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

而且 HttpSession 中的很多内存问题都与这种暂时性但未被清除的数据有关(根本忘记,或在发生异常时未清除,或当用户不尊重常规流程:点击Back,使用以前的书签,点击不同的菜单或其他任何东西).

缓存库以获得正确的生命周期

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

这个想法是你有一个技术代码(与一个功能页面无关,而是全局实现,例如使用 ServletFilter ...)确保在不再需要对象后始终完成清理.

您可以使用以下策略中的一个(或根据需要使用多个)来设计此缓存来清理缓存.每项政策都与功能寿命相关:

  • 对于仅与一个屏幕相关的数据(但有几个请求:重新加载屏幕、Ajax 请求...),缓存一次只能存储一个屏幕的数据(对于每个会话),称之为currentScreenCache";.这保证,如果用户转到另一个屏幕(即使以非托管方式),新屏幕将覆盖currentScreenCache".信息,之前的信息可​​以被垃圾收集.
<块引用>

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

  • 对于仅用于一系列连接屏幕的数据(称为功能模块),同样适用于模块级别.
<块引用>

实现:和之前一样,每个请求都必须携带模块ID...

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

实现:缓存库本身就支持这个限制因素,还有几个……

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

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

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

Hi what do you think about this problem?

We do have too much information in HttpSession, because much information is computed and a few large graph of objects are needed to store between requests finally.

Is it appropriate to use any cache like memcache or so? Or is it the same as increasing memory for JVM?

There's fear of storing it in DB between requests. What would you use if we are getting OutOfMemory error?

Thank you.

解决方案

I think the real point is the lifespan of your data.


Think about these two characteristics of the HttpSession:

  • When in a cluster, the container is responsible for replicating the HttpSession. This is good (you don't have to manage this yourself), but can be dangerous in terms of performance if this leads to too much exchanges... If your application is not clustered, forget about this point.
  • The lifespan of the HttpSession can be a few minutes or a few hours, that is while the user keeps active. This is perfect for information that has that lifespan (connection information, preferences, authorizations...). But it is not appropriate for data that is useful from one screen to the next, let's call it transient+ data.

If you have clustering needs, the database takes care of it. But beware, you can't cache anything in memory then.

Storing in the database has even longer lifespan (persistent between session, and even between reboots!), so the problem would be even worth (except you trade a memory problem for a performance problem).

I think this is the wrong approach for data whose lifespan is not expected to be persistent ...


Transient data

If data is useful only for one request, then it is typically stored in the HttpRequest, fine.

But if it is used for a few requests (interactions within one screen, or within a screen sequence like an assistant ..), the HttpRequest is too short to store it, but the HttpSession is too long. The data needs to be cleaned regularly.

And many memory problems in the HttpSession are related to such data that is transient but was not cleaned (forgotten at all, or not cleaned when an Exception, or when the user doesn't respect the regular flow: hits Back, use a previous bookmark, clic on a different menu or whatever).

Caching library to have the correct lifespan

To avoid this cleaning effort altogether (and avoid the risks of OutOfMemory when things go wrong), you can store information in a data structure that has the right lifespan. As the container doesn't provide this (it is application-related anyway), you need to implement this yourself using a cache library (like the ones mentioned; we use EhCache).

The idea is that you have a technical code (not related to one functional page, but implemented globally, such as with a ServletFilter ...) that ensures cleaning is always done after the objects are not needed any more.

You can design this cache using one (or several as needed) of the following policies for cleaning the cache. Each policy related to a functional lifespan:

  • for data only related to one screen (but several requests : reloading of the screen, Ajax requests ...), the cache can store data only for one screen at a time (for each session), call it "currentScreenCache". That guarantees that, if the user goes to another screen (even in an unmanaged way), the new screen will override the "currentScreenCache" information, and the previous information can be garbage-collected.

Implementation idea: each request must carry its screenId, and the technical code responsible for clearing the cache detects when, for the current HttpSession id, the current screenId doesn't match the one in the cache. Then it cleans or resets that item in the cache.

  • for data only used in a series of connected screens (call it a functional module), the same applies at the level of the module.

Implementation: same as before, every request has to carry the module id...

  • for data that is expensive to recompute, the cache library can be configured to store the last X computed ones (the previous ones are considered less-likely to be useful in the near-future). In typical usage, the same ones are asked for regularly, so you have many cache hits. On intensive use, the X limit is reached and the memory doesn't inflate, preventing OutOfMemory errors (at the expense of re-computation the next time).

Implementation: cache libraries support natively this limiting factor, and several more...

  • for data that is only valid for a few minutes, the cache library can natively be configured to discard it after that delay...

  • ... many more, see the caching library configuration for other ideas.

Note: Each cache can be application-wide, or specific to a user, a HttpSession id, a Company id or other functional value...

这篇关于HttpSession 中的信息过多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆