Tomcat多實(shí)例單應(yīng)用部署方案

一、Tomcat部署的場(chǎng)景分析

通常,我們對(duì)tomcat部署需求可以分為幾種:?jiǎn)螌?shí)例單應(yīng)用,單實(shí)例多應(yīng)用,多實(shí)例單應(yīng)用,多實(shí)例多應(yīng)用。

  • 對(duì)于第一種場(chǎng)景,如果不要求周期性地維護(hù)tomcat版本,一般的做法是把打好的war包丟到webapps目錄下,然后執(zhí)行startup.sh腳本,并且可以在瀏覽器里訪問(wèn)就行了。
  • 對(duì)于第二種場(chǎng)景,是把多個(gè)應(yīng)用程序的war包放在同一個(gè)tomcat的webapps目錄,這樣一來(lái),關(guān)閉和啟動(dòng)tomcat會(huì)影響所有項(xiàng)目。
  • 對(duì)于第三種場(chǎng)景,各個(gè)tomcat都運(yùn)行同一個(gè)應(yīng)用程序,對(duì)應(yīng)地需要修改不同的監(jiān)聽端口,這種方式通常會(huì)和apache httpd或者nginx整合使用,做一些負(fù)載均衡的處理。
  • 對(duì)于第四種場(chǎng)景相當(dāng)于第一種場(chǎng)景的復(fù)數(shù)形式,除了修改不同的監(jiān)聽端口,沒(méi)有本質(zhì)區(qū)別。

一般來(lái)說(shuō),多實(shí)例部署tomcat,可以充分利用系統(tǒng)資源,不過(guò)這種方式,也有幾個(gè)方面需要考慮:

  • 多實(shí)例tomcat的更新維護(hù),例如對(duì)tomcat進(jìn)行升級(jí)等操作,我們需要考慮如何能“優(yōu)雅”地對(duì)所有實(shí)例進(jìn)行升級(jí)
  • 盡量不要影響應(yīng)用程序,在更新tomcat時(shí),一不小心就把conf目錄等全部覆蓋,所以盡量要把配置文件和安裝目錄隔離
  • 對(duì)于單應(yīng)用來(lái)說(shuō),如果將war包分別置于各個(gè)tomcat的webapps目錄,那么在發(fā)布新版本的war時(shí),可能會(huì)出現(xiàn)某個(gè)實(shí)例更新失敗,導(dǎo)致用戶在訪問(wèn)時(shí)可能會(huì)訪問(wèn)到不同版本的web app,因此,比較好的方式就是所有tomcat實(shí)例都統(tǒng)一指向同一個(gè)應(yīng)用程序

本文重點(diǎn)闡述多實(shí)例應(yīng)用的部署方案,但是為了解決上述幾個(gè)問(wèn)題,我們需要先來(lái)了解一下tomcat的一些基本情況。

二、基本要點(diǎn)

2.1 分離目錄

首先來(lái)看一下tomcat的目錄結(jié)構(gòu),一個(gè)剛解壓出來(lái)的tomcat打包文件應(yīng)該有以下幾個(gè)目錄

目錄 作用
bin 主要存放腳本文件,例如比較常用的windows和linux系統(tǒng)中啟動(dòng)和關(guān)閉腳本
conf 主要存放配置文件,其中最重要的兩個(gè)配置文件是server.xml和web.xml
lib 主要存放tomcat運(yùn)行所依賴的包
logs 主要存放運(yùn)行時(shí)產(chǎn)生的日志文件,例如catalina.{date}.log等
temp 存放tomcat運(yùn)行時(shí)產(chǎn)生的臨時(shí)文件,例如開啟了hibernate緩存的應(yīng)用程序,會(huì)在該目錄下生成一些文件
webapps 部署web應(yīng)用程序的默認(rèn)目錄
work 主要存放由JSP文件生成的servlet(java文件以及最終編譯生成的class文件)

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

  • CATALINA_HOME:即指向Tomcat安裝路徑的系統(tǒng)變量
  • CATALINA_BASE:即指向活躍配置路徑的系統(tǒng)變量
    通過(guò)設(shè)置這兩個(gè)變量,就可以將tomcat的安裝目錄和工作目錄分離,從而實(shí)現(xiàn)tomcat多實(shí)例的部署。

Tomcat官方文檔指出,CATALINA_HOME路徑的路徑下只需要包含bin和lib目錄,這也就是支持tomcat軟件運(yùn)行的目錄,而CATALINA_BASE設(shè)置的路徑可以包括上述所有目錄,不過(guò)其中bin和lib目錄并不是必需的,缺省時(shí)會(huì)使用CATALINA_HOME中的bin和conf。如此,我們就可以使用一個(gè)tomcat安裝目錄部署多個(gè)tomcat實(shí)例,這樣的好處在于方便升級(jí),就可以在不影響tomcat實(shí)例的前提下,替換掉CATALINA_HOME指定的tomcat安裝目錄。

tomcat目錄結(jié)構(gòu)

2.2 修改server.xml

這里不詳細(xì)分析server.xml中每一個(gè)配置項(xiàng),網(wǎng)上也有很多這方面的文檔。下面主要說(shuō)明監(jiān)聽端口和Host的配置內(nèi)容。
在server.xml中配置了四個(gè)監(jiān)聽端口,分別是:

  • Server Port:該端口用于監(jiān)聽關(guān)閉tomcat的shutdown命令,默認(rèn)為8005
    Connector Port:該端口用于監(jiān)聽HTTP的請(qǐng)求,默認(rèn)為8080
  • AJP Port:該端口用于監(jiān)聽AJP( Apache JServ Protocol )協(xié)議上的請(qǐng)求,通常用于整合Apache Server等其他HTTP服務(wù)器,默認(rèn)為8009
  • Redirect Port:重定向端口,出現(xiàn)在Connector配置中,如果該Connector僅支持非SSL的普通http請(qǐng)求,那么該端口會(huì)把https的請(qǐng)求轉(zhuǎn)發(fā)到這個(gè)Redirect Port指定的端口,默認(rèn)為8443

可見,如果不是使用AJP協(xié)議連接tomcat,只需要保證多實(shí)例中的Server Port和Connect Port不同即可。

再來(lái)說(shuō)Host配置,Host就是所謂的虛擬主機(jī),對(duì)應(yīng)包含了一個(gè)或者多個(gè)web應(yīng)用程序,默認(rèn)的Host配置如下

<Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">

其中:

  • name: 虛擬主機(jī)的名稱,一臺(tái)主機(jī)表示了完全限定的域名或IP地址,默認(rèn)為localhost,同時(shí)也是唯一的host,進(jìn)入tomcat的所有http請(qǐng)求都會(huì)映射到該主機(jī)上
  • appBase:web應(yīng)用程序目錄的路徑,可以是CATALINA_HOME的相對(duì)路徑,也可以寫成絕對(duì)路徑,默認(rèn)情況下為$CATALINA_HOME/webapps
    unpackWARs: 表示是否自動(dòng)解壓war包
  • autoDeploy:所謂的熱部署,即在tomcat正在運(yùn)行的情況下,如果有新的war加入,則會(huì)立即執(zhí)行部署操作
  • 另外再介紹一個(gè)Host中的屬性—deployOnStartup:表示tomcat啟動(dòng)時(shí)是否自動(dòng)部署appBase目錄下所有的Web應(yīng)用程序,默認(rèn)為true。這個(gè)屬性和autoDeploy會(huì)產(chǎn)生兩次部署的“副作用”:一次是tomcat啟動(dòng)時(shí)就開始部署,第二次就是autoDeploy引起的熱部署。因此最好將autoDeploy置為false

在部署多實(shí)例單應(yīng)用的時(shí)候,默認(rèn)的$CATALINA/webapps會(huì)因?yàn)閠omcat安裝目錄升級(jí)產(chǎn)生不必要的麻煩,我們考慮將appBase的目錄統(tǒng)一到另外的路徑下。

最后再說(shuō)明一下Context的配置,它出現(xiàn)在Host配置內(nèi),一個(gè)Context的配置就代表了一個(gè)web應(yīng)用程序,如果配置多應(yīng)用程序,就需要在Host下配置多個(gè)Context,一個(gè)簡(jiǎn)單的Context配置如下

<Context path="/some" docBase="someapp.war" >

其中:

  • path:表示訪問(wèn)入口,例如,path=”/abc”,則訪問(wèn)localhost:8080/abc時(shí),就可以訪問(wèn)該Context對(duì)應(yīng)的應(yīng)用程序。如果path=””,則直接用localhost:8080就可以訪問(wèn)
  • docBase:表示應(yīng)用程序的解包目錄或者war文件路徑,是Host的appBase配置目錄的相對(duì)路徑,也可以是直接寫成絕對(duì)路徑,但是不要將appBase的值,作為docBase配置路徑的前綴,例如appBase=”somedir”,docBase=”somedir-someapp.war”,這樣的配置會(huì)導(dǎo)致部署錯(cuò)誤

通過(guò)配置Host的appBase和Context的docBase兩個(gè)屬性,可以將應(yīng)用程序的文件和tomcat相關(guān)的目錄進(jìn)行分離,這樣webapps目錄也就沒(méi)有作用了。

最終我們可以得到多實(shí)例單應(yīng)用部署方案的整體框架:


部署框架

三、方案實(shí)施

現(xiàn)在假設(shè)我們有一臺(tái)已經(jīng)配置好Java環(huán)境的服務(wù)器:

# export JAVA_HOME=/application/jdk
# export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
# export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
 
# java -version
java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

另外假設(shè)一個(gè)完好的可以運(yùn)行的web應(yīng)用程序已經(jīng)打包成some.war,放在/data/www目錄下,其中包含一個(gè)簡(jiǎn)單的index.jsp

<html>
<body>
<h2>Hello World!</h2>
</body>
</html>

3.1 下載并解壓tomcat

# cd /usr/local
# wget -q http://mirrors.cnnic.cn/apache/tomcat/tomcat-7/v7.0.72/bin/apache-tomcat-7.0.72.tar.gz
# tar zxf apache-tomcat-7.0.72.tar.gz
# ls apache-tomcat-7.0.72
bin  conf  lib  LICENSE  logs  NOTICE  RELEASE-NOTES  RUNNING.txt  temp  webapps  work

3.2 配置tomcat多實(shí)例

可以用一小段腳本來(lái)完成批量創(chuàng)建的工作

for ((i=1;i<=3;i++))
do
    mkdir /application/tomcat7-$i/{work,temp,conf,logs} -p
    cp -a /application/tomcat7-$i/application/tomcat7-$i && \
    sed -i 22s@8005@80${i}5@ /application/tomcat7-$i/conf/server.xml // 修改tomcat關(guān)閉端口
    sed -i 71s@8080@808${i}@ /application/tomcat7-$i/conf/server.xml // 修改Http監(jiān)聽端口
    sed -i 93s@8009@80${i}9@ /application/tomcat7-$i/conf/server.xml // 修改AJP端口
    sed -i '125s@appBase="webapps"@appBase="/data/www"@' /application/tomcat7-$i/conf/server.xml //統(tǒng)一web應(yīng)用程序的路徑
    sed -i '126s@autoDeploy="true"@autoDeploy="false"@' /application/tomcat7-$i/conf/server.xml //關(guān)閉自動(dòng)部署
    sed -i '126a <Context path="" docBase="/data/www/some.war" />' /application/tomcat7-$i/conf/server.xml //配置Context信息,指向some.war的路徑
done

3.3 創(chuàng)建啟停腳本

#!/bin/sh
 
CUR_DIR=`dirname $BASH_SOURCE`
export JAVA_HOME="/application/jdk"
export CATALINA_BASE=`readlink -f $CUR_DIR`
export CATALINA_HOME="/usr/local/apache-tomcat-7.0.72"
 
case $1 in
 start)
 [ -f $CATALINA_HOME/bin/startup.sh ] && $CATALINA_HOME/bin/startup.sh
 ;;
 stop)
 [ -f $CATALINA_HOME/bin/shutdown.sh ] && $CATALINA_HOME/bin/shutdown.sh
 ;;
 restart)
 [ -f $CATALINA_HOME/bin/shutdown.sh ] && $CATALINA_HOME/bin/shutdown.sh && \
 [ -f $CATALINA_HOME/bin/startup.sh ] && $CATALINA_HOME/bin/startup.sh
 ;;
 *)
 echo "usage : $0 { start | stop | restart }"
 return 1;
 ;;
esac
 
return 0

把該腳本放在tomcat7-1,tomcat7-2和tomcat7-3目錄下
現(xiàn)在我們的目錄結(jié)構(gòu)如下

# ls tomcat7-1 tomcat7-2 tomcat7-3 
tomcat7-1:
conf  logs  temp  tomcat.sh  work
 
tomcat7-2:
conf  logs  temp  tomcat.sh  work
 
tomcat7-3:
conf  logs  temp  tomcat.sh  work

3.4 啟動(dòng)tomcats

# cd /application
# . tomcat7-1/tomcat.sh start 
# . tomcat7-2/tomcat.sh start
# . tomcat7-3/tomcat.sh start
 
# netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      25757/sshd                
tcp        0      0 :::8029                     :::*                        LISTEN      21225/java          
tcp        0      0 ::ffff:127.0.0.1:8035       :::*                        LISTEN      21186/java          
tcp        0      0 :::8039                     :::*                        LISTEN      21186/java          
tcp        0      0 ::ffff:127.0.0.1:8015       :::*                        LISTEN      21002/java          
tcp        0      0 :::8081                     :::*                        LISTEN      21002/java          
tcp        0      0 :::8082                     :::*                        LISTEN      21225/java          
tcp        0      0 :::8083                     :::*                        LISTEN      21186/java          
tcp        0      0 :::8019                     :::*                        LISTEN      21002/java          
tcp        0      0 :::22                       :::*                        LISTEN      25757/sshd          
tcp        0      0 ::ffff:127.0.0.1:8025       :::*                        LISTEN      21225/java

可以看到8081,8082,8083等其他端口都已經(jīng)啟動(dòng),現(xiàn)在可以使用curl命令進(jìn)行訪問(wèn)

# curl localhost:8081
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>
 
# curl localhost:8082
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>
 
# curl localhost:8083
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>

完成!

四、參考文獻(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容