java - Tomcat session 驱逐以避免内存不足错误

标签 java memory session tomcat session-timeout

我们正在 Tomcat 5.5 中使用 StandardManager 进行 session (在内存中)运行供应商提供的 Web 应用程序。由于 session 可能变得相当大(20M+),堆空间耗尽是一个严重的问题。如果可能的话,用户希望将 session 保留几个小时,但宁愿驱逐 session 也不愿耗尽堆空间。供应商似乎没有在 session 对象中正确实现可序列化,因此切换到持久 session 管理器实现不是一个选项。

Tomcat 允许设置 maxActiveSessions 属性,该属性将限制管理器中的 session 总数。但是,当达到该限制时,在某些现有 session 到期之前,无法创建新 session 。我们希望首先破坏最近最少使用的 session 。

理想情况下,当堆使用量接近“Xmx”设置时,我们希望使一些最近未使用的 session 过期,即使它们还不够老,无法无条件过期。一个非常古老的 Tomcat 开发人员邮件列表线程建议这可能会允许拒绝服务攻击*,但是,由于此应用程序仅在公司网络内可用,因此我们并不担心。

我考虑过扩展 StandardManager 来覆盖 processExpires() 并在堆使用率大于最大值的 85% 时破坏额外的 session 。然而,这在实践中似乎有点问题。如果堆的大部分未被引用,并且垃圾收集器将能够收集大量对象(如果它不厌其烦地运行)以将堆减少到最大值的 50%,该怎么办?我会不必要地使 session 过期。我想我们可以通过一些积极的垃圾收集设置来减轻这种风险。另外,我如何知道 session 过期节省了多少内存?我必须等待几个 GC 周期才能确定。也许我可以采取保守的方法,在每个后台进程周期删除最多 N 个 session ,直到内存降至可接受的阈值以下。我可以序列化 session 作为估计有多少内容将被 GC 处理的方法,但这依赖于供应商实现 Serialized 并将实例变量适本地标记为 transient 。

有人解决这个问题了吗?作为短期解决方案,我们正在增加堆大小,但这种创可贴也有其缺点。

  • 他们指的是一个公共(public)网站,其中将在登录前创建 session 。有人可能会导致创建许多新 session 并排挤实际使用的 session 。

更新:我们确实对系统架构没有太多控制权,而且我们特别无法减少 session 使用。然而,我们可以按照自己的意愿对容器进行修改。然而,Tomcat 是唯一受供应商支持的开源 servlet 容器。

最佳答案

您的选择似乎是:

  1. 减少空闲 session 超时,
  2. 使 session 持久化(可能仅在用户登录后),
  3. 减少每个 session 对象使用的内存,
  4. 增加 Tomcat 实例的内存,
  5. 运行服务的多个实例,并在其前面放置一个负载均衡器。

从技术角度来看,3 是最好的解决方案……如果可行的话。其他都有缺点。

用内存来做聪明的事情只是一个创可贴。从用户的角度来看,它使您的网站的行为更难以理解。此外,如果您的用户群/流量呈上升趋势,那么您只是在推迟寻找可持续解决方案的问题。

关于java - Tomcat session 驱逐以避免内存不足错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1197530/

相关文章:

java - Android:如何使用图像按钮?

java - 用户在for循环java中输入更大的数字,错误 "bad operand type"

java - 如何使用Spring MVC在JSP上显示图像

java - Spark 打印数据帧而不会耗尽内存

apache - 我所有脚本中的 PHP 内存不足

php - 登录时 Symfony2 和 PHP SDK 4.0 session 问题

oracle - 如何在PL/SQL Developer中保持连接状态?

java - 如何打印数组中的重复项?

c - 获取 DLL 函数的内存地址

java - Tomcat 7 创建多个 session