4

我已经读过 Tomcat 5.5+ 可以在不重新启动的情况下将战争部署到 Tomcat 服务器。这听起来很棒,但我想我对这个功能及其可靠性持怀疑态度。我以前的经验(使用 Websphere)是最好的做法是重新启动服务器以避免内存问题等。所以我想获得有关 Tomcat 可能存在哪些陷阱的反馈。

(为了清楚我的经验,我为一家将应用程序开发人员与应用程序服务器工程师分开的大公司开发了 5 年的 Java Web 应用程序 - 我们使用 Websphere - 所以我在运行/配置任何应用程序方面没有很多经验应用服务器自己)

4

2 回答 2

8

一般来说,有多种类型的泄漏,它们适用于重新部署方案。对于生产系统,如果可能,最好执行重新启动,因为当今应用程序中使用了许多不同的组件和库,很难找到它们,甚至更难修复它们。特别是。如果您无法访问所有源代码。

  • 内存泄漏
  • Thread 和 ThreadLocal 泄漏
  • 类加载器泄漏
  • 系统资源泄露
  • 连接泄漏

ClassLoader 泄漏是在重新部署时咬人的

它们可能是由一切引起的。真的,我的意思是一切:

  • 定时器:定时器有线程,运行时创建的线程继承当前上下文类加载器,也就是Tomcat的WebappClassloader。
  • ThreadLocals: ThreadLocals 绑定到线程。应用服务器使用线程池。当 ThreadLocal 绑定到 Thread 并且 Thread 被归还给池时,如果没有人正确地 remove() 它, ThreadLocal 将保留在那里。经常发生并且很难找到(ThreadLocals 没有名称,除了很少使用的 Spring NamedThreadLocal)。如果 ThreadLocal 包含由 WebappClassloader 加载的类,则您会遇到 ClassLoader 泄漏。
  • 缓存:例如 EhCache CacheManager
  • 反射: JavaBeans Introspector(例如持有类或方法缓存)
  • JDBC 驱动程序:它们不应该在.war文件中。由于静态注册表泄漏
  • 缓存 ClassLoader 的静态库,例如 Commons-Logging LogFactory

具体到Tomcat,我的经验如下:

  • 对于具有“干净”库的简单应用程序,它在 Tomcat 中运行良好
  • Tomcat 非常努力地清理由 WebappClassloader 加载的类。例如,当取消部署 web 应用程序时,类的所有静态字段都设置为 null。这有时会导致在取消部署时运行代码时出现 NullPointerExceptions,例如使用 Logger 的后台作业
  • Tomcat 有一个监听器,它可以清理更多的东西。它最近被调用org.apache.catalina.core.JreMemoryLeakPreventionListener并提交给Tomcat 6.x

我写了一篇关于我在进行重新部署压力测试时的泄漏经验的博客文章- 试图“修复”企业级 Java Web 应用程序的所有可能泄漏。

于 2010-02-19T18:42:30.130 回答
2

热部署非常好,因为它通常比启动和关闭服务器要快得多。

mhaller 写了很多关于避免泄漏的文章。另一个问题是活跃用户让他们的会话在应用程序“重启”后仍然存在。有几件事情必须注意,但总而言之,它们的会话必须是可序列化的,然后在之后正确反序列化。如果您有有状态的数据库连接等,这可能会有点棘手,但是如果您的代码对数据库故障很健壮,那应该不会太糟糕。

另请注意,某些 IDE 允许在保存修改后的源文件时更新 WAR 内的代码(与应用程序相同),而不必重新部署。MyEclipse 做得很好。

于 2010-02-20T12:12:41.477 回答