在不重新启动的情况下将应用程序部署/重新部署到Tomcat的Pitfals

sha*_*une 3 java tomcat hotdeploy

我已经读过Tomcat 5.5+可以在没有重启的情况下将战争部署到Tomcat服务器.这听起来很棒,但我想我对这个功能太过持怀疑态度,而且它的可靠性.我以前的经验(使用Websphere)是重启服务器以避免内存问题等最佳实践.所以我想得到关于Tomcat可能存在哪些陷阱的反馈.

(为了清楚我的经验,我为一家大型公司开发了java网络应用程序5年,该公司将应用程序开发人员与应用程序服务器工程师分开 - 我们使用了Websphere - 因此我没有很多运行/配置任何经验的经验应用服务器自己)

mha*_*ler 6

通常,存在多种类型的泄漏,它们适用于重新部署方案.对于生产系统,如果可能的话,执行重启确实是最好的,因为在今天的应用程序中使用了很多不同的组件和库,很难找到它们,甚至更难修复它们.ESP.如果您无法访问所有源代码.

  • 内存泄漏
  • Thread和ThreadLocal泄漏
  • ClassLoader泄漏
  • 系统资源泄漏
  • 连接泄漏

ClassLoader泄漏是重新部署时的漏洞.

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

  • 定时器:定时器具有在运行时创建的线程和线程继承当前上下文类加载器,这意味着Tomcat的WebappClassloader.
  • ThreadLocals: ThreadLocals绑定到线程.应用服务器使用线程池.当ThreadLocal绑定到一个Thread并且Thread被返回给池时,如果没有人正确地删除()它,ThreadLocal将保留在那里.经常发生并且很难找到(ThreadLocals没有名称,除了很少使用的Spring NamedThreadLocal).如果ThreadLocal包含WebappClassloader加载的类,则会出现ClassLoader泄漏.
  • 缓存:例如EhCache CacheManager
  • 反思: JavaBeans Introspector(例如,持有Class或Method缓存)
  • JDBC驱动程序:它们不应该在.war文件中.静态注册表导致泄漏
  • 缓存ClassLoaders的静态库,例如Commons-Logging LogFactory

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

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

我写了一篇博客文章,讲述了我在进行重新部署压力测试时遇到泄漏的经历 - 试图"修复"企业级Java Web应用程序的所有可能漏洞.