歡迎轉載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
