導讀:
昨天在跟羣友作技術交流的時候,瞭解到,有不少大公司都是採用了高可用的,分佈式的,實例沉餘1+臺。可是在小公司的同窗也不少,他們反映並非全部公司都有那樣的資源來供你調度。每每公司只會給你一臺機器,由於有些應用掛了公司也不會有損失的,咱們每每一臺機器就能夠搞定。
可是,咱們也要爲咱們作出來的應用負責,畢竟東西作出來是爲了給人用的,若是作出來的東西常常掛了,談何使用,在前期,若是公司資源緊張的狀況下,能夠不能夠作高可用,多機器的沉餘部署。可是至少是在但機上有2個進程在跑。so,在這裏咱們就說說這個,如何作單機多實例的部署。
在這裏談談,在只有單機的資源下,如何把單機的資源壓榨出來,用好單機。html
一般,咱們對tomcat單機部署需求能夠分爲幾種:java
第一種場景:這是咱們開發中常常用到的,若是不要求週期性地維護tomcat版本,通常的作法是把打好的war包丟到webapps目錄下,而後執行startup.sh腳本,而且能夠在瀏覽器裏訪問就好了。
第二種場景:是把多個應用程序的war包放在同一個tomcat的webapps目錄,這樣一來,關閉和啓動tomca,或tomcat掛掉會影響全部項目。
第三種場景: 各個tomcat都運行同一個應用程序,對應地須要修改不一樣的監聽端口,這種方式一般會和apache httpd或者nginx整合使用,作一些負載均衡的處理。
第四種場景: 至關於第一種場景的複數形式,除了修改不一樣的監聽端口,沒有本質區別。linux
通常來講,多實例部署tomcat,能夠充分利用系統資源,不過這種方式,也有幾個方面須要考慮:
多實例tomcat的更新維護,例如對tomcat進行升級等操做,咱們須要考慮如何能「優雅」地對全部實例進行升級
儘可能不要影響應用程序,在更新tomcat時,一不當心就把conf目錄等所有覆蓋,因此儘可能要把配置文件和安裝目錄隔離
對於單應用來講,若是將war包分別置於各個tomcat的webapps目錄,那麼在發佈新版本的war時,可能會出現某個實例更新失敗,致使用戶在訪問時可能會訪問到不一樣版本的web app,所以,比較好的方式就是全部tomcat實例都統一指向同一個應用程序,這樣作,就能夠多個tomcat用一份應用源碼,簡單部署,單機高可用也能實現(要配合nginx).
本文重點闡述多實例應用的部署方案,可是爲了解決上述幾個問題,咱們須要先來了解一下tomcat的一些基本狀況。nginx
這裏有一臺服務器,3臺tomcat服務,以及一臺tomcat的解構圖。web
目錄 | 做用 |
---|---|
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:shell
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 serve.xml 配置結構
Container容器子容器間關係圖apache
交互圖windows
對比下Tomcat serve.xml 的配置瀏覽器
<?xml version="1.0" encoding="UTF-8"?> <Server port="8005" shutdown="SHUTDOWN"> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Service name="Catalina"> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine> </Service> </Server>
四、實戰
端口配置
在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
虛擬主機配置
再來講Host配置,Host就是所謂的虛擬主機,對應包含了一個或者多個web應用程序,默認的Host配置以下
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
其中:
name: 虛擬主機的名稱,一臺主機表示了徹底限定的域名或IP地址,默認爲localhost,同時也是惟一的host,進入tomcat的全部http請求都會映射到該主機上
appBase:web應用程序目錄的路徑,能夠是CATALINA_HOME的相對路徑,也能夠寫成絕對路徑,默認狀況下爲$CATALINA_HOME/webappsunpackWARs: 表示是否自動解壓war包
autoDeploy:所謂的熱部署,即在tomcat正在運行的狀況下,若是有新的war加入,則會當即執行部署操做
另外再介紹一個Host中的屬性—deployOnStartup:表示tomcat啓動時是否自動部署appBase目錄下全部的Web應用程序,默認爲true。這個屬性和autoDeploy會產生兩次部署的「反作用」:一次是tomcat啓動時就開始部署,第二次就是autoDeploy引發的熱部署。所以最好將autoDeploy置爲false
在部署多實例單應用的時候,默認的$CATALINA/webapps會由於tomcat安裝目錄升級產生沒必要要的麻煩,咱們考慮將appBase的目錄統一到另外的路徑下。
Context的配置
最後再說明一下Context的配置,它出如今Host配置內,一個Context的配置就表明了一個web應用程序,若是配置多應用程序,就須要在Host下配置多個Context,一個簡單的Context配置以下
<Context path="/some" docBase="someapp.war" >
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目錄也就沒有做用了。
步驟1:
下載並解壓tomcat
步驟2:
對Tomcat目錄做如下調整:
在tomcat安裝目錄下建立a.ttlsa.com、b.ttlsa.com,而且將conf、logs、webapp、temp、work目錄拷貝到這兩個目錄,而後tomcat安裝目錄只須要留下bin、a.ttlsa.com、b.ttlsa.com、lib這4個目錄便可。配置後的目錄結構以下:
若是要度tomcat 進行升級,咱們只是須要對tomcat的lib 和 bin 目錄進行升級便可。
步驟3:
配置站點server.xml
配置a.ttlsa.com
<?xml version="1.0" encoding="UTF-8"?> <!-- 8005 改成8005 --> <Server port="8005" shutdown="SHUTDOWN"> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Service name="Catalina"> <Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> --> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <!-- <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> --> <Host name="localhost" appBase="F:\data\www\a.ttlsa.com" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context path="" docBase="" reloadable="true"> <valve className="org.apache.catalina.valves.RemoteAddrValve" /> </Context> </Host> </Engine> </Service> </Server>
配置b.ttlsa.com
<?xml version="1.0" encoding="UTF-8"?> <!-- 8005 改成8006 --> <Server port="8002" shutdown="SHUTDOWN"> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Service name="Catalina"> <Connector port="8082" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> --> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <!-- <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> --> <Host name="localhost" appBase="F:\data\www\a.ttlsa.com" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context path="" docBase="" reloadable="true"> <valve className="org.apache.catalina.valves.RemoteAddrValve" /> </Context> </Host> </Engine> </Service> </Server>
建立多實例啓動腳本
# description: 啓動tomcat多實例.# . /etc/init.d/functions RETVAL=$? # tomcat實例目錄 export CATALINA_BASE="$PWD" # tomcat安裝目錄 export CATALINA_HOME="/usr/local/tomcat-7.0.50" # 可選 export JVM_OPTIONS="-Xms128m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=512m" case "$1" in start) if [ -f $CATALINA_HOME/bin/startup.sh ];then echo $"Start Tomcat" $CATALINA_HOME/bin/startup.sh fi ;; stop) if [ -f $CATALINA_HOME/bin/shutdown.sh ];then echo $"Stop Tomcat" $CATALINA_HOME/bin/shutdown.sh fi ;; *) echo $"Usage: $0 {start|stop}" exit 1 ;; esac exit $RETVAL
這段shell 腳本比較簡單,主要是設置環境變量,接受命令參數 RETVAL=?,來執行不一樣的命令。RETVAL=start/stop等exportCATALINABASE=」?,來執行不一樣的命令。RETVAL=start/stop等exportCATALINABASE=」PWD」 表示設置當前路徑爲 CATALINA_BASE 的環境變量,通常狀況下CATALINA_BASE 和 CATALINA_HOME 是默認同樣的。
啓動腳本賦權限
# chmod a+x tomcat.sh
五、啓動測試
啓動/關閉a.ttlsa.com
啓動 # cd /usr/local/tomcat-7.0.50/a.ttlsa.com/ # ./tomcat.sh start 關閉 # cd /usr/local/tomcat-7.0.50/a.ttlsa.com/ # ./tomcat.sh stop
啓動/關閉b.ttlsa.com
啓動 # cd /usr/local/tomcat-7.0.50/a.ttlsa.com/ # ./tomcat.sh start 關閉 # cd /usr/local/tomcat-7.0.50/a.ttlsa.com/ # ./tomcat.sh stop
備註:必定須要cd到tomcat.sh的當前目錄下執行才能夠
在win7 下,須要建立在a.ttlsa.com 和b.ttlsa.com下面建立 startup.bat 來啓動
@echo off set JAVA_HOME=D:\Program Files\Java\jdk1.8.0_112 set PATH=%JAVA_HOME%\bin;%PATH% set CATALINA_BASE=%CD% cd E:\tomcat-8.5.6\bin catalina.bat start
shell 腳本入門參考:http://sishuok.com/forum/blogPost/list/5655.html這段是在win7 下雲的bat腳本,於shell腳本同理,set CATALINA_BASE=%CD% 也是設置環境變量,CD 能夠獲取當前的路徑。
單個Tomcat應用多個tomcat實例的配置到此,就結束了。
此外,咱們在這裏的基礎上進行系統的擴展,好比若是個人Tomcat應用掛掉了,個人整個應用都將不可用了,咱們應該如何處理?
咱們能夠把Tomcat複製多份,在單機的狀況下,開多一個Tomcat進程,在配合Nginx 來配置,就能實現Tomcat的自動切換,這些內容,有空再寫。
若是須要操做多個實例顯得比較麻煩,你們能夠自行寫統一的腳本。
Linux 下的實現基本一致。
這樣的好處是,顯而易見的,這樣能開啓Tomcat的多個進程,即多臺tomcat,掛了也不太怕,還有其餘tomcat應用支撐,代碼實例咱們發版本的時候,只須要發佈一份,實例代碼易於維護。
可是,咱們網站的域名和端口通常是同一採用80端口,統一的域名,而如今咱們開啓tomcat只能一個使用80端口,顯然是不合適的·,爲此咱們會引入負載均衡的nginx來配置。
nginx 採用80 端口,tomcat分別採用8080, 8081, 8082 這樣就能讓咱們的程序穩定的運行。
這樣,咱們就能進最大的限度來壓榨單機的性能,保證應用程序的穩定的運行。
而然,單機否則有單機的瓶頸,畢竟單機中的cpu 已經各類硬件的限制,會大大影響實例程序的跑動,在這時,就再也不是單機能抗的動的了,咱們須要分析程序的瓶頸在那?數據庫,那就把數據庫單獨分出去,單獨一臺機器,是文件圖片服務器,就把他分出去。若是是應用程序太大,就要考慮把應用實例進行拆解爲不一樣哦那個的組件,單獨部署,這就是分佈式部署。
固然,這都是後話,只有程序複雜到必定的程度,並體量很大的話,纔會作這種架構的演變,成本和技術投入的難度也會相應的變大。
本章,只侷限於如何玩好單機的基礎上來討論,對於分佈式的那塊,筆者能力有限,尚且還不能徹底駕馭,不作分享。
在上面的配置的基礎上,咱們在進一步進行擴展,進行實例的均衡和熱備。
能夠在一個服務器掛了的狀況下連到另一個,那怎麼弄呢?
其實很簡單,在upstream中的local_tomcat中配置多一個server。
在上面,個人a.ttlsa.com 和 b.ttlsa.com 都是訪問 F:\data\www\a.ttlsa.com 下的源碼的index.jsp 頁面,
爲了能觀察,nginx 的keepAlive 的效果,我作一下修改:
a.ttlsa.com —> F:\data\www\a.ttlsa.com index.jsp 中文字是 1
b.ttlsa.com —> F:\data\www\b.ttlsa.com index.jsp 中文字是 2
upstream local_tomcat { server localhost:8081 weight=1; server localhost:8082 weight=5; }
server { listen 80; server_name localhost:8081; #charset koi8-r; #access_log logs/host.access.log main; #location / { # root html; # index index.html index.htm; #} location / { proxy_pass http://local_tomcat; }
在一般的狀況下,咱們通常是指向一份源碼就足夠了,而且設置權值,減輕應用的壓力。同時也不會出現單點的狀況。
補充:nginx.con 配置
#user nobody; worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; upstream local_tomcat { server localhost:8081 weight=1; server localhost:8082 weight=5; } server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; #location / { # root html; # index index.html index.htm; #} location / { proxy_pass http://local_tomcat; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
綜上:咱們作到了多臺tomcat 可是咱們也能作到tomcat的簡單升級,而且實現實例的負載均衡,已經應用的主備,在也不用擔憂應用掛掉而睡不了覺了。
本次的實驗資源供下載:http://download.csdn.net/detail/a82793510/9687715