使用Tomcat的Reload提高开发速度(翻译)

时间:2021-07-17 19:43:27

欢迎转载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