欢迎转载http://www.cnblogs.com/coodream2009,有翻译的不太准确的地方请大家指出,我继续修改完善。
按照Java Servlet规范第四部分推荐的,Tomcat系统的实现了reload Java类来进行应用的部分更新,而不用重新启动整个服务器。
这个特性对于开发来说非常重要,因为随着服务器启动和重新启动的时间得增加,对开发者产出有着严重的影响。事实上,不论是个人项目还是企业级项目,Java EE栈应用服务器重启时间比较慢是导致Tomcat广泛应用的原因之一。
然而,即便Tomcat不能快速启动,它还是能够在运行中reload一个应用。通过仅仅加载独立应用中改变的类,开发者能在几秒内而不是几分钟内获得新功能的启动和运行。
(本段为Tcat的广告时间)Tcat的中心管理控制台让您深刻了解web应用程序的性能。可靠的停止、启动、部署和解部署应用,通过email、电话或者更多的途径获得自定义报警。马上下载Tcat吧。
在这篇文章中,我们将针对所有的不同的机制,提供合理配置和Tomcat实例加载应用程序和java类,包括:
通过服务器重启reload
利用Tomcat管理器手动reload
通过Context设置热reload
利用WatchedResources参数热reload
利用集成开发环境如eclipse热reload
对于为什么在生产环境不应该使用自动加载,我们也说明了一些原因,并由一些解决建议。
如何进行reload工作
在我们开始之前,让我们快速的定义几个在文章中用到的术语,以避免歧义。
本文中,你会看到reloading和redeploying应用程序,尽管他们都是服务器用于处理应用程序的变化,这两个术语并不能互换。
对Apache Tomcat服务器来说,reload一个应用程序意味着在一个给定的Context上调用Standard Context类的一个方法,方法名称是StandardContext.reload() 。这个方法创建了一个新的类加载器和新的servlets,回收了旧的servlets所有的引用,然后在servlet上调用servlet.init()方法,给servlet一个初始化状态,通过新的类加载器触发所有类和库的reload。
相比之下,reployment意味着先从部署目录全部删除这个应用程序,然后在服务器的appBase目录重新部署。
关于服务器重启的单词
最基础的,零失误reload web应用程序的方式就是重新启动Tomcat服务器。如果你在服务器上运行多个应用程序,这种重启的方法尽管慢而且有些麻烦,在很多情况下完全的服务器重启来reload你的应用程序是最合适的方法。
这些特殊的场景包括你的应用程序有多部分组成,这些组成部分必须在Catalina的server.xml文件中配置,比如GlobalNamingResources,或者你对你的docBase使用了符号链接来设置应用程序配置。
重启Tomcat服务器也是停止和重启你的应用程序的一种方式,它允许reload一些元素比如web.xml文件(尽管重启这些文件的方式无需停止服务)。
通过Tomcat Manager进行reload
Tomcat Manager,是一个包含所有标准分布的Tomcat的web应用程序,有能力reload web应用程序(比如启动、停止、部署和解除部署它们),即使用用程序的Context没有被设置为“reloadable”。在生产环境中reload一个应用程序,将Tomcat的自动reload特性设置为禁止,是特别有用的,否则在低性能的环境中自动reload会引起内存问题。
Tomcat Manager一旦正确设置,它就能通过web控制台http:/{host}:{port}/manager/html来访问,或者通过多个基于URI的命令公开脚本功能。
从web控制台reload一个应用程序,导航到“应用程序列表”选项卡。你可以从服务器部署的所有应用程序中选择一个应用程序去reload。通过URI命令reload一个应用程序,使用如下的格式:
http:/[hostname]:[port]/manager/reload?path=[/path/to/your/webapp]
即使你没有声明你的应用程序Context是reloadable的,这些命令也可以使用。需要注意的是,截至到Tomcat6.0.26版本,这种方式管理应用程序不能reload那些部署为war包文件的应用程序,只能管理部署为文件夹的应用程序。
使用Manager来reload以war包部署的已经产生变化的应用程序,你可以先解除部署然后再重新部署它。Tomcat Manager也不能用于reload发生变化的web.xml文件。为了实现这种变化而不重新启动整个服务器,使用Manager简单的停止然后启动这个应用程序。换一种方式,你也可以用WatchedResources来设置这些文件。
出于明显的安全原因,Tomcat Manager默认是禁止的,打开它需要进行多个Tomcat设置。
要获取使用Tomcat Manager的reload功能和配置的详细指导,还有一些其它的特性,需要访问Tomcat Manager文章(https://www.mulesoft.com/cn/tomcat-manager)。
通过Context settings来进行热reload
在开发的面向细节的阶段,比如优化阶段,频繁的进行小的改动很必要,很多情况是仅仅测试一些方法,这些方法是简单特性的编码。在这种场景下,通过Manager手动触发每一个reload应用程序是不可行的或者是效率不够。
为了解决这类问题,Tomcat包含了一种叫做“backgroundProcess”的方法,作为Catalina组件的一部分。一般来说,这个过程提供session过期,但是如果正确配置,它也能监测所有的应用程序的类发生变化,假如有任何改变都会调用reload。
为了配置reloading,需要在应用程序的Context元素中添加“reloadable”属性,或者在Context片段或者在server.xml中。
<Context ... reloadable="true">
在Context元素中的container上,在backgroundProcess运行之前你可以配置以秒为单位的延迟,通过backgroundProcessorDelay属性配置,尽管这个值也能被Host和Engine继承。
利用WatchedResource参数进行热reload
当你定义一个Context是“reloadable”时,Catalina的默认行为是观察它的类,库和web.xml配置文件,如果发生变化则触发reload。有时候,你想在列表中增加其他文件,比如日志配置文件。在这些场景中,你能够使用Context中嵌套WatchedResource元素来指向附加的文件,这些文件Tomcat能够观察。使用如下的语法:
<Host>
<Context ... reloadable="true">
<WatchedResource>path/to/watched/resource</WatchedResource>
<WatchedResource>another/path/to/another/resource</WatchedResource>
</Context>
</Host>
需要注意的是一对WatchedResource标签只能包含一个文件。如果你想为所有的Contexts创建全局settings,你需要在Context.xml、server.xml文件或者Catalina的conf/Context.xml文件中配置这些setting。
利用eclipse IDE进行热reload
通过配置你的Context,当类发生变化时能自动reload,使用web工具平台集成Tomcat和eclipse(或其他的Java IDE),你能增加热reload功能到你的开发环境。
按照以下简单的配置步骤:
先将Tomcat集成到eclipse环境中,查相关资料实现。
根据前面介绍的配置步骤,在你的Tomcat服务器上允许热reload
配置eclipse的工作目录直接指向启动的Tomcat服务器的文件夹结构,这可能需要一些允许配置。
当服务器运行时直接编辑你的类,当你保存应用程序的时候观察Tomcat自动reload它们。
迁移到生产环境
热reloading在开发环境是非常有用的,但把应用程序迁移到生产环境,你需要确保禁止所有的自动reloading配置。下面有一些说明为什么这个很重要。
reload类是复杂的。如果新类创建后,旧类的引用被保留下来,旧类就不会被合理的回收,这就是大家熟知的内存泄露问题。这是任何Java平台都会碰到的常见的问题。
除了这种考虑外,Tomcat使用Servlet的init()方法来reload应用程序,需要整个应用程序都被初始化,随着程序复杂度的增加,多步骤过程开销会越来越高。
最后,自动reload失败会导致状态数据丢失,这在生产环境中是不可接受的。
由于以上原因,当把应用程序迁移到生产环境,最好的做法是禁止自动reloading,而是依靠Tomcat Manager或者管理工具如Tcat来管理应用程序。
参考资料:https://www.mulesoft.com/cn/tcat/tomcat-reload