如果您認為Tomcat不能再進步,那您就錯了。 Tomcat 7引入了所謂的并行部署 。 這是由SpringSource / VMWare貢獻的。
簡而言之,并行部署是一種能夠并行部署一個以上版本的Web應用程序的功能,使所有版本都可以在完全相同的URL下使用。
考慮一下。 如果您有新版本的應用程序,則只需將其放入運行舊版本的Tomcat中 ,它將運行。 實際上,它們都會起作用。 Tomcat處理應用程序版本之間的所有會話管理和流量路由。 無需重新啟動Tomcat 。 無需停止處理請求。 無需與您的老板談論停機時間。 您的老板無需與任何客戶談論停機時間。
讓我們看看實際情況,對吧? 使用下面的命令,您可以啟動一個最小的Web應用程序來演示此功能。
$ mkdir WEB-INF
$ echo "" > WEB-INF/web.xml
$ echo 'old version ' > index.jsp
$ jar cf foo##001.war WEB-INF index.jsp
$ echo 'NEW version ' > index.jsp
$ jar cf foo##002.war WEB-INF index.jsp
現在,您有兩個名為foo ## 001.war和foo ## 002.war的 Web應用程序。 ## 001和## 002指定WAR文件的版本號。 每個都有自己的索引頁面,該頁面顯示當前時間以及是舊的還是新的Web應用程序。 創建此功能的人員選擇了一個非常簡單的解決方案,用于告訴Tomcat什么是替代版本。 您要做的就是在WAR的文件名上加上## <version> 。 簡單有效,如果看起來有些古怪。
現在部署Web應用程序的“舊”版本。
$ cp foo##001.war apache-tomcat-7.0.12/webapps/
打開瀏覽器,輸入WAR文件的URL(例如http:// localhost:8080 / foo )并注意時間。 請注意,您在URL上看不到版本號。 頁面每秒自動刷新。 在表面之下, Tomcat將與您的瀏覽器建立會話。 以后再說。
現在部署Web應用程序的“新”版本。
$ cp foo##002.war apache-tomcat-7.0.12/webapps/
請注意,在已經打開的瀏覽器窗口中,時間仍在滴答作響,并且仍顯示舊版本。 打開第二個瀏覽器,在該瀏覽器中,也打開http:// localhost:8080 / foo 。 為了獲得最佳結果,請使用完全不同的瀏覽器以避免任何會話異常。 我使用Safari和Opera進行了測試。
您應該看到第二個瀏覽器選擇了新的Web應用程序,而舊的Web應用程序仍在使用第一個瀏覽器。

很整潔吧?
好的,您是否破壞了部署并想回滾? 很簡單,只需刪除新版本, Tomcat就會自動退回到使用舊版本。 辛苦了 現在就試試:
$ rm apache-tomcat-7.0.12/webapps/foo##002.war
您會注意到網頁會自動切換為使用舊版本的應用程序。
您將必須制定自己的部署策略。 您可能選擇讓舊版本耗盡。 在舊應用程序上的所有會話都到期后,您可以從Tomcat中刪除舊部署。 另一方面,您可以只保留舊代碼。 它不會造成任何傷害。
當您想開始在Tomcat服務器上使用版本化的WAR文件時,需要考慮一些事項。 因此,在您離開并更改公司的部署策略之前,請檢查以下列表。
- 內部緩存應該是直寫的,并且很快過期
- 您需要啟用會話
- 日志去哪兒了?
- 磁盤文件和目錄需要共享
- 沒有TCP套接字監聽器
- 您的應用必須能夠取消部署
我將按順序解釋這些內容。 大多數是主題的變體; 考慮一下您的代碼對機器資源所做的假設。
內部緩存應該是直寫的,并且很快過期
同一Web應用程序的不同版本各自具有自己的類上下文。 這意味著需要檢查Web應用程序中的所有本地緩存??。 如果您主動緩存并長時間保留緩存的信息,則該Web應用程序的一個版本可能看不到另一個版本所做的更改。
設想一個情況,其中兩個版本的Web應用程序都使用相同的數據庫,并且都具有本地緩存??以避免訪問該數據庫。 如果該Web應用程序的一個版本更改了數據庫中的記錄,則其他版本將看不到該更改,直到該信息自己的緩存版本過期為止。
如果您在Web應用程序中執行任何內存中緩存,請在確定緩存不會提供不可接受的過時信息之前不要使用并行部署。
您需要啟用會話
Tomcat使用其自己的會話管理來確定應由哪個版本的Web應用程序處理哪些請求。 如果您打算自己實現會話處理,或者如果您在Tomcat中關閉了會話處理,那么并行部署將對您不起作用。
日志去哪兒了?
您可能指定將日志記錄寫入某個地方的日志文件。 如果未在日志文件名中使用應用程序的完整上下文名稱,則可能會遇到兩種情況:Web應用程序的兩個版本都寫入同一日志文件。 這樣做的問題是,您可能不知道應用程序的哪個版本生成了在該文件中找到的輸出。
磁盤文件和目錄需要共享
Java EE設計者的意圖一直是使Web應用程序獨立于底層機器和文件系統。 如果您的應用程序使用數據文件,請花點時間考慮一下當您的Web應用程序的兩個版本開始讀寫它們時會發生什么。
特別是,請考慮將Java的監視器和鎖限制在單個上下文中。 因此,如果您使用某種類型的鎖來保護對文件的訪問,則擁有該Web應用程序的兩個版本意味著您在JVM中具有兩個鎖,從而可能允許兩個線程對其進行訪問。
沒有TCP套接字監聽器
一些應用程序不僅僅服務于HTTP請求。 他們有自己的TCP套接字處理程序為客戶端提供服務。 通過部署一個以上版本的Web應用程序,您可以獲得多個偵聽器。 顯然這是行不通的。 只有一個偵聽器可以在任何給定端口上偵聽。
您的應用必須能夠取消部署
如果您希望能夠回退已損壞的發行版,或者希望清理Web應用程序的舊的,未使用的版本,則需要徹底取消部署Web應用程序。 幸運的是, Tomcat也可以幫助您。
希望這些警告不會使您停止使用Tomcat中的零停機時間部署。 您可能需要解決一些問題才能使其正常運行。 但是,讓我們面對現實吧,通過使您的應用程序對資源的假設更少,無論如何您將獲得一個更強大的應用程序。
PS。 我喜歡將SVN修訂號用作WAR版本命名方案。 因此,我的WAR文件被命名為foo ## <svn版本=””>。war 。 唯一需要注意的是,將版本作為字符串進行比較以確定版本順序。 因此,您可能必須對版本號進行零填充以確保正確訂購。
參考: Tomcat中的零停機部署(和回滾); JCG合作伙伴 Kees Jan在Java Monitor論壇上 的演練和清單
相關文章:
- 每個程序員都應該知道的事情
- 正確記錄應用程序的10個技巧
- 軟件設計法則
- Java最佳實踐系列
- 生存在狂野西部開發過程中的9條提示
翻譯自: https://www.javacodegeeks.com/2011/06/zero-downtime-deployment-and-rollback.html