一、瞭解tomcat
Tomcat不是一個完整意義上的Jave EE(j2ee)服務器,由於它沒有提供完整的Java EE企業應用平臺的API。可是因爲Tomcat遵循apache開源協議,而且對當前Java開發框架開源組件Structs、Spring和Hibernate等實現完美支持,所以tomcat被衆多企業用來部署配置衆多的Java應用程序,實現替代一些商業的Java應用服務器。
二、Tomcat的目錄結構
要部署使用tomcat,則必須瞭解tomcat的目錄結構以及各目錄的做用。這裏以tomcat7爲例
安裝Tomcat,再次不在闡述,[詳情請移步]
html
進入tomcat安裝目錄下:前端
|-- bin
| |-- bootstrap.jar tomcat啓動時所依賴的一個類,在啓動tomcat時會發現Using CLASSPATH: 是加載的這個類
| |-- catalina-tasks.xml 定義tomcat載入的庫文件,類文件
| |-- catalina.bat
| |-- catalina.sh tomcat單個實例在Linux平臺上的啓動腳本
| |-- commons-daemon-native.tar.gz jsvc工具,可使tomcat已守護進程方式運行,需單獨編譯安裝
| |-- commons-daemon.jar jsvc工具所依賴的java類
| |-- configtest.bat
| |-- configtest.sh tomcat檢查配置文件語法是否正確的Linux平臺腳本
| |-- cpappend.bat
| |-- daemon.sh tomcat已守護進程方式運行時的,啓動,中止腳本
| |-- digest.bat
| |-- digest.sh
| |-- setclasspath.bat
| |-- setclasspath.sh
| |-- shutdown.bat
| |-- shutdown.sh tomcat服務在Linux平臺下關閉腳本
| |-- startup.bat
| |-- startup.sh tomcat服務在Linux平臺下啓動腳本
| |-- tomcat-juli.jar
| |-- tomcat-native.tar.gz 使tomcat可使用apache的apr運行庫,以加強tomcat的性能需單獨編譯安裝
| |-- tool-wrapper.bat
| |-- tool-wrapper.sh
| |-- version.bat
| `-- version.sh 查看tomcat以及JVM的版本信息
|-- conf 顧名思義,配置文件目錄
| |-- catalina.policy 配置tomcat對文件系統中目錄或文件的讀、寫執行等權限,及對一些內存,session等的管理權限
| |-- catalina.properties 配置tomcat的classpath等
| |-- context.xml tomcat的默認context容器
| |-- logging.properties 配置tomcat的日誌輸出方式
| |-- server.xml tomcat的主配置文件
| |-- tomcat-users.xml tomcat的角色(受權用戶)配置文件
| `-- web.xml tomcat的應用程序的部署描述符文件
|-- lib
|-- logs 日誌文件默認存放目錄
|-- temp
| `-- safeToDelete.tmp
|-- webapps tomcat默認存放應用程序的目錄,比如apache的默認網頁存放路徑是/var/www/html同樣
| |-- docs tomcat文檔
| |-- examples tomcat自帶的一個獨立的web應用程序例子
| |-- host-manager tomcat的主機管理應用程序
| | |-- META-INF 整個應用程序的入口,用來描述jar文件的信息
| | | `-- context.xml 當前應用程序的context容器配置,它會覆蓋tomcat/conf/context.xml中的配置
| | |-- WEB-INF 用於存放當前應用程序的私有資源
| | | |-- classes 用於存放當前應用程序所須要的class文件
| | | |-- lib 用於存放當前應用程序鎖須要的jar文件
| | | `-- web.xml 當前應用程序的部署描述符文件,定義應用程序所要加載的serverlet類,以及該程序是如何部署的
| |-- manager tomcat的管理應用程序
| |-- ROOT 指tomcat的應用程序的根,若是應用程序部署在ROOT中,則可直接經過http://ip:port 訪問到
`-- work 用於存放JSP應用程序在部署時編譯後產生的class文件java
三、瞭解tomcat的主配置文件(server.xml)結構及含義
以下圖所示,前端請求被tomcat直接接收或者由前端的代理,經過HTTP,或者AJP代理給Tomcat,此時請求被tomcat中的connector接收,不一樣的connector和Engine被service組件關聯起來,在一個Engine中定義了許多的虛擬主機,由Host容器定義,每個Host容器表明一個主機,在各自的Host中,又能夠定義多個Context,用此來定義一個虛擬主機中的多個獨立的應用程序。linux
四、單實例應用程序配置一例web
- 規劃:
- 網站網頁目錄:/web/www 域名:www.test1.com
- 論壇網頁目錄:/web/bbs URL:bbs.test1.com/bbs
- 網站管理程序:$CATALINA_HOME/wabapps URL:manager.test.com 容許訪問地址:172.23.136.*
- conf/server.xml
- <Server port="8005" shutdown="SHUTDOWN">
- <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
- <Listener className="org.apache.catalina.core.JasperListener" />
- <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>
- <!-- 定義的一個名叫「UserDatabase」的認證資源,將conf/tomcat-users.xml加載至內存中,在須要認證的時候到內存中進行認證 -->
- <Service name="Catalina">
- <!-- # 定義Service組件,同來關聯Connector和Engine,一個Engine能夠對應多個Connector,每一個Service中只能一個Engine --!>
- <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
- <!-- 修改HTTP/1.1的Connector監聽端口爲80.客戶端經過瀏覽器訪問的請求,只能經過HTTP傳遞給tomcat。 -->
- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
- <Engine name="Catalina" defaultHost="test.com">
- <!-- 修改當前Engine,默認主機是,www.test.com -->
- <Realm className="org.apache.catalina.realm.LockOutRealm">
- <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
- resourceName="UserDatabase"/>
- </Realm>
- # Realm組件,定義對當前容器內的應用程序訪問的認證,經過外部資源UserDatabase進行認證
- <Host name="test.com" appBase="/web" unpackWARs="true" autoDeploy="true">
- <!-- 定義一個主機,域名爲:test.com,應用程序的目錄是/web,設置自動部署,自動解壓 -->
- <Alias>www.test.com</Alias>
- <!-- 定義一個別名www.test.com,相似apache的ServerAlias -->
- <Context path="" docBase="www/" reloadable="true" />
- <!-- 定義該應用程序,訪問路徑"",即訪問www.test.com便可訪問,網頁目錄爲:相對於appBase下的www/,即/web/www,而且當該應用程序下web.xml或者類等有相關變化時,自動重載當前配置,即不用重啓tomcat使部署的新應用程序生效 -->
- <Context path="/bbs" docBase="/web/bbs" reloadable="true" />
- <!-- 定義另一個獨立的應用程序,訪問路徑爲:www.test.com/bbs,該應用程序網頁目錄爲/web/bbs -->
- <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/web/www/logs"
- prefix="www_access." suffix=".log"
- pattern="%h %l %u %t "%r" %s %b" />
- <!-- 定義一個Valve組件,用來記錄tomcat的訪問日誌,日誌存放目錄爲:/web/www/logs若是定義爲相對路徑則是至關於$CATALINA_HOME,並不是相對於appBase,這個要注意。定義日誌文件前綴爲www_access.並以.log結尾,pattern定義日誌內容格式,具體字段表示能夠查看tomcat官方文檔 -->
- </Host>
- <Host name="manager.test.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
- <!-- 定義一個主機名爲man.test.com,應用程序目錄是$CATALINA_HOME/webapps,自動解壓,自動部署 -->
- <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="172.23.136.*" />
- <!-- 定義遠程地址訪問策略,僅容許172.23.136.*網段訪問該主機,其餘的將被拒絕訪問 -->
- <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/web/bbs/logs"
- prefix="bbs_access." suffix=".log"
- pattern="%h %l %u %t "%r" %s %b" />
- <!-- 定義該主機的訪問日誌 -->
- </Host>
- </Engine>
- </Service>
- </Server>
- conf/tomcat-users.xml
- <?xml version='1.0' encoding='utf-8'?>
- <tomcat-users>
- <role rolename="manager-gui" />
- <!-- 定義一種角色名爲:manager-gui -->
- <user username="cz" password="manager$!!110" roles="manager-gui" />
- <!-- 定義一個用戶的用戶名以及密碼,並賦予manager-gui的角色 -->
- </tomcat-users>
由以上配置不難看出存在的一個問題。若是咱們想要對其中一個應用程序的配置作一些修改,那麼就必須從新啓動tomcat,那樣勢必就會影響到另外兩個應用程序的正常服務。所以以上配置是不適合線上使用的,所以須要將其配置爲多實例,每一個實例只跑一個獨立的應用程序,那樣咱們應用程序之間就不會在互相受到影響。可是咱們將面臨這樣一個問題,80端口只能被一個HTTP/1.1 Connector監聽,而三個tomcat實例則至少須要3個HTTP/1.1 Connector,這樣咱們就須要一個前端代理作分發處理,接收HTTP 80端口的請求,按域名經過每一個tomcat實例的AJP/1.3 Connector傳遞請求。而前端的代理選擇apache,基於這樣的思路,咱們還能夠作到tomcat的負載均衡,並且apache會將接收的HTTP超文本傳輸報文從新封裝成二進制格式經過AJP/1.3 協議傳遞給後端的tomcat處理,在效率上也是有明顯的提高。apache
五、結合apache構造多實例tomcat集羣
apache結合tomcat的方式主要有三種:mod_jk,ajp_proxy,http_proxy(以http協議代理給tomcat),而當前使用最多的仍是要數mod_jk。由於mod_jk出現的較早,技術已經至關成熟,並且具有集羣節點健康檢測功能,支持大型的AJP數據包。bootstrap
安裝apache,tomcat這裏不在詳述,須要瞭解,[請狂戳這裏]
安裝tomcat-connectors
tar zxvf tomcat-connectors-1.2.30-src.tar.gz
cd tomcat-connectors/src
./configure --with-apxs=/usr/local/apache/bin/apxs
make && make installvim
①單獨創建httpd-jk.conf後端
單獨創建httpd-jk.conf文件用來配置mod_jk的相關設置
vim /usr/local/apache2/conf/extra/httpd-jk.conf瀏覽器
LoadModule jk_module modules/mod_jk.so
# 配置apache裝載mod_jk.so模塊
JkWorkersFile /usr/local/apache/conf/extra/workers.properties
# 指定保存了worker相關工做屬性定義的配置文件
JkLogFile /usr/local/apache/logs/mod_jk.log
# 定義mod_jk模塊的日誌文件
JkLogLevel info
# 定義mod_jk模塊日誌的記錄級別
②創建worker相關工做屬性定義的配置文件
vim /usr/local/apache/conf/extra/workers.properties
worker.list=Cluster1,stat
worker.web2.port=8003
worker.web2.host=172.23.138.19
worker.web2.type=ajp13
worker.web2.lbfactor=1
worker.web3.port=8003
worker.web3.host=172.23.136.144
worker.web3.type=ajp13
worker.web3.lbfactor=1
worker.Cluster1.type=lb
worker.Cluster1.balance_workers=web2,web3
worker.Cluster1.sticky_session = 1
worker.stat.type=status
worker.list=Cluster2
worker.manager2.port=7003
worker.manager2.host=172.23.138.19
worker.manager2.type=ajp13
worker.manager2.lbfactor=1
worker.manager3.port=7003
worker.manager3.host=172.23.136.144
worker.manager3.type=ajp13
worker.manager3.lbfactor=1
worker.Cluster2.type=lb
worker.Cluster2.balance_workers=manager2,manager3
worker.Cluster2.sticky_session = 1
③配置後端tomcat多實例
使用腳本快速部署tomcat實例,修改新實例的AJP/1.3 Connector的監聽端口,HTTP/1.1 Connector的監聽端口以及Server容器的監聽端口。腳本內容以下:
- #!/bin/bash
- # when:2013-01-21
- # who: czlinux@163.com
- #
- Java_Home=/usr/java/jdk1.7.0_10
- Tomcat_Home=/usr/local/tomcat_7
- Tomcat_User=tomcat
- New_instance=/usr/local/new
- if [ ! -d $New_instance ];then
- mkdir -p $New_instance
- else
- echo "The parh alreadly exists..."
- exit
- fi
- id $Tomcat_User 2&> /dev/null & useradd -r $Tomcat_User
- cp -r $Tomcat_Home/conf $New_instance
- mkdir -p $New_instance/{logs,temp,webapps/ROOT,work}
- cat > $New_instance/tomcat.sh << EOF
- #!/bin/sh
- JAVA_HOME=`echo $Java_Home`
- JAVA_OPTS="-Xms64m -Xmx128m"
- CATALINA_HOME=`echo $Tomcat_Home`
- CATALINA_BASE=`echo $New_instance`
- export JAVA_HOME JAVA_OPTS CATALINA_HOME CATALINA_BASE
- su `echo $Tomcat_User` \$CATALINA_HOME/bin/catalina.sh \$1
- EOF
- cat > $New_instance/webapps/ROOT/index.jsp << EOF
- <html><body><center>
- <h1>This is a new tomcat instance!</h1>
- </br>
- Now time is: <%=new java.util.Date()%>
- </center>
- </body></html>
- EOF
- chown $Tomcat_User:$Tomcat_User -R $New_instance
如今後端每臺tomcat節點的配置情況以下:
www.test.com實例:
<Server port="8000">
<Connector port="8001" protocol="HTTP/1.1">
<Connector port="8003" protocol="AJP/1.3">
</Server>
manager.test.com實例:
<Server port="7000">
<Connector port="7001" protocol="HTTP/1.1">
<Connector port="7003" protocol="AJP/1.3">
</Server>
使用新實例中的tomcat.sh進行啓動每一個實例
④配置多域名的負載均衡
vim /usr/local/apache/conf/extra/httpd-vhosts.conf
NameVirtualHost *:80
<VirtualHost *:80>
ServerName www.test.com
JkMount /* Cluster1
</VirtualHost>
<VirtualHost *:80>
ServerName manager.test.com
JkMount /* Cluster2
JkMount /status stat
</VirtualHost>
到此基於多域名多實例的tomcat負載均衡集羣構建完成,啓動apache便可,基於當前結構還可結合持久會話管理器(PersistentManager)來實現會話持久的效果。
本文出自 「My---Dream.*」 博客,請務必保留此出處http://grass51.blog.51cto.com/4356355/1123400