Tomcat多例項單應用部署方案

fullstackyang發表於2016-12-27

一、Tomcat部署的場景分析

通常,我們對tomcat部署需求可以分為幾種:單例項單應用,單例項多應用,多例項單應用,多例項多應用。

對於第一種場景,如果不要求週期性地維護tomcat版本,一般的做法是把打好的war包丟到webapps目錄下,然後執行startup.sh指令碼,並且可以在瀏覽器裡訪問就行了。

對於第二種場景,是把多個應用程式的war包放在同一個tomcat的webapps目錄,這樣一來,關閉和啟動tomcat會影響所有專案。

對於第三種場景,各個tomcat都執行同一個應用程式,對應地需要修改不同的監聽埠,這種方式通常會和apache httpd或者nginx整合使用,做一些負載均衡的處理。

對於第四種場景相當於第一種場景的複數形式,除了修改不同的監聽埠,沒有本質區別。

一般來說,多例項部署tomcat,可以充分利用系統資源,不過這種方式,也有幾個方面需要考慮:

  • 多例項tomcat的更新維護,例如對tomcat進行升級等操作,我們需要考慮如何能“優雅”地對所有例項進行升級
  • 儘量不要影響應用程式,在更新tomcat時,一不小心就把conf目錄等全部覆蓋,所以儘量要把配置檔案和安裝目錄隔離
  • 對於單應用來說,如果將war包分別置於各個tomcat的webapps目錄,那麼在釋出新版本的war時,可能會出現某個例項更新失敗,導致使用者在訪問時可能會訪問到不同版本的web app,因此,比較好的方式就是所有tomcat例項都統一指向同一個應用程式

本文重點闡述多例項應用的部署方案,但是為了解決上述幾個問題,我們需要先來了解一下tomcat的一些基本情況

二、基本要點

2.1 分離目錄

首先來看一下tomcat的目錄結構,一個剛解壓出來的tomcat打包檔案應該有以下幾個目錄

bin 主要存放指令碼檔案,例如比較常用的windows和linux系統中啟動和關閉指令碼
conf 主要存放配置檔案,其中最重要的兩個配置檔案是server.xml和web.xml
lib 主要存放tomcat執行所依賴的包
logs 主要存放執行時產生的日誌檔案,例如catalina.{date}.log等
temp 存放tomcat執行時產生的臨時檔案,例如開啟了hibernate快取的應用程式,會在該目錄下生成一些檔案
webapps 部署web應用程式的預設目錄
work 主要存放由JSP檔案生成的servlet(java檔案以及最終編譯生成的class檔案)

再介紹兩個tomcat中比較重要的概念(通常也是兩個系統變數)——CATALINA_HOME和CATALINA_BASE:

  • CATALINA_HOME:即指向Tomcat安裝路徑的系統變數
  • CATALINA_BASE:即指向活躍配置路徑的系統變數

通過設定這兩個變數,就可以將tomcat的安裝目錄和工作目錄分離,從而實現tomcat多例項的部署。

Tomcat官方文件指出,CATALINA_HOME路徑的路徑下只需要包含bin和lib目錄,這也就是支援tomcat軟體執行的目錄,而CATALINA_BASE設定的路徑可以包括上述所有目錄,不過其中bin和lib目錄並不是必需的,預設時會使用CATALINA_HOME中的bin和conf。如此,我們就可以使用一個tomcat安裝目錄部署多個tomcat例項,這樣的好處在於方便升級,就可以在不影響tomcat例項的前提下,替換掉CATALINA_HOME指定的tomcat安裝目錄。

tomcat-dirs

2.2 修改server.xml

這裡不詳細分析server.xml中每一個配置項,網上也有很多這方面的文件。下面主要說明監聽埠和Host的配置內容。

在server.xml中配置了四個監聽埠,分別是:

  • Server Port:該埠用於監聽關閉tomcat的shutdown命令,預設為8005
  • Connector Port:該埠用於監聽HTTP的請求,預設為8080
  • AJP Port:該埠用於監聽AJP( Apache JServ Protocol )協議上的請求,通常用於整合Apache Server等其他HTTP伺服器,預設為8009
  • Redirect Port:重定向埠,出現在Connector配置中,如果該Connector僅支援非SSL的普通http請求,那麼該埠會把https的請求轉發到這個Redirect Port指定的埠,預設為8443

可見,如果不是使用AJP協議連線tomcat,只需要保證多例項中的Server Port和Connect Port不同即可。

再來說Host配置,Host就是所謂的虛擬主機,對應包含了一個或者多個web應用程式,預設的Host配置如下

其中:

  • name: 虛擬主機的名稱,一臺主機表示了完全限定的域名或IP地址,預設為localhost,同時也是唯一的host,進入tomcat的所有http請求都會對映到該主機上
  • appBase:web應用程式目錄的路徑,可以是CATALINA_HOME的相對路徑,也可以寫成絕對路徑,預設情況下為$CATALINA_HOME/webapps
  • unpackWARs: 表示是否自動解壓war包
  • autoDeploy:所謂的熱部署,即在tomcat正在執行的情況下,如果有新的war加入,則會立即執行部署操作
  • 另外再介紹一個Host中的屬性—deployOnStartup:表示tomcat啟動時是否自動部署appBase目錄下所有的Web應用程式,預設為true。這個屬性和autoDeploy會產生兩次部署的“副作用”:一次是tomcat啟動時就開始部署,第二次就是autoDeploy引起的熱部署。因此最好將autoDeploy置為false

在部署多例項單應用的時候,預設的$CATALINA/webapps會因為tomcat安裝目錄升級產生不必要的麻煩,我們考慮將appBase的目錄統一到另外的路徑下。

最後再說明一下Context的配置,它出現在Host配置內,一個Context的配置就代表了一個web應用程式,如果配置多應用程式,就需要在Host下配置多個Context,一個簡單的Context配置如下

其中:

  • path:表示訪問入口,例如,path=”/abc”,則訪問localhost:8080/abc時,就可以訪問該Context對應的應用程式。如果path=””,則直接用localhost:8080就可以訪問
  • docBase:表示應用程式的解包目錄或者war檔案路徑,是Host的appBase配置目錄的相對路徑,也可以是直接寫成絕對路徑,但是不要將appBase的值,作為docBase配置路徑的字首,例如appBase=”somedir”,docBase=”somedir-someapp.war”,這樣的配置會導致部署錯誤

通過配置Host的appBase和Context的docBase兩個屬性,可以將應用程式的檔案和tomcat相關的目錄進行分離,這樣webapps目錄也就沒有作用了。

最終我們可以得到多例項單應用部署方案的整體框架:

tomcat-instances

三、方案實施

現在假設我們有一臺已經配置好Java環境的伺服器:

另外假設一個完好的可以執行的web應用程式已經打包成some.war,放在/data/www目錄下,其中包含一個簡單的index.jsp

XHTML

3.1 下載並解壓tomcat

3.2 配置tomcat多例項

可以用一小段指令碼來完成批量建立的工作

3.3 建立啟停指令碼

把該指令碼放在tomcat7-1,tomcat7-2和tomcat7-3目錄下

現在我們的目錄結構如下

3.4 啟動tomcats

可以看到8081,8082,8083等其他埠都已經啟動,現在可以使用curl命令進行訪問

完成!

四、參考文獻

  • (美)布里泰恩, (美)達爾文, 吳豪. Tomcat權威指南[M]. 中國電力出版社, 2009.
  • tomcat官方文件:https://tomcat.apache.org/tomcat-7.0-doc/RUNNING.txt

相關文章