最近要配置tomcat叢集,在網上搜了很多文章,但照着步驟一步一步做到最後卻無法成功,着使我費了兩天的勁檢視了apache 和 tomcat的大量文檔,才将問題一一解決。為友善自己和新手配置tomcat叢集,我将整理好的過程曬一曬,希望可以幫到後來人少走一些彎路。
==================
目标:
使用 apache 和 tomcat 配置一個可以應用的 web 網站,要達到以下要求:
1、 Apache 做為 HttpServer ,後面連接配接多個 tomcat 應用執行個體,并進行負載均衡。
2、 為系統設定 Session 逾時時間,包括 Apache 和 tomcat
3、 為系統屏蔽檔案清單,包括 Apache 和 tomcat
注:本例程以一台機器為例子,即同一台機器上裝一個apache和2個Tomcat。
一、前期準備工作:安裝用的程式(前提保證已安裝了JDK1.5以上的版本)
APAHCE 2.2.8下載下傳:apache_2.2.8-win32-x86-no_ssl.msi
TOMCAT6.0.14下載下傳:apache-tomcat-6.0.14.zip直接解壓。
二、安裝過程
APAHCE安裝目錄:D:/Apache。
兩個TOMCAT目錄:自行解壓到(D:/TomcatCluster/)下。
分别為 tomcat6-a,tomcat6-b
三、配置
1、Apache配置
1.1 httpd.conf配置
修改APACHE的配置檔案D:/Apache/conf/httpd.conf
這裡并沒有使用mod_jk.so進行apache和tomcat的連結,從2.X以後apache自身已內建了mod_jk.so的功能。隻需簡單的把下面幾行去掉注釋,就相當于以前用mod_jk.so比較繁瑣的配置了。
這裡主要采用了代理的方法,就這麼簡單。
将以下Module的注釋去掉
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
再找到
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
加上index.jsp修改成
<IfModule dir_module>
DirectoryIndex index.html index.jsp
</IfModule>
此處添加index.jsp 主要為了配置完成以後利用index.jsp輸出測試資訊!
在 httpd.conf 最後面加入
ProxyRequests Off
<proxy balancer://cluster>
BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2
</proxy>
上面的兩個BalancerMember成員是我們配置的tomcat叢集。
1.2 httpd-vhosts.conf設定
接下來進行虛拟主機的設定。
APACHE的虛拟主機設定如下:
首先要修改 conf/httpd.conf
找到
# Virtual hosts
#Include conf/extra/httpd-vhosts.conf
把Include語句注釋去掉。改成
# Virtual hosts
Include conf/extra/httpd-vhosts.conf
在檔案(extra/httpd-vhosts.conf)最下面加入
<VirtualHost *:80>
ServerAdmin adminname
ServerName localhost
ServerAlias localhost
ProxyPass / balancer://cluster/ stickysession=jsessionid nofailover=On lbmethod=bytraffic
ProxyPassReverse / balancer://cluster/
</VirtualHost>
其中的域名和路徑根據你自己情況設定
負載均衡有三種方式,可以通過設定 lbmethod 選擇自己需要的方式,詳細可檢視apache文檔
proxy是位于用戶端與實際的伺服器之間的伺服器,一般稱為facade server,負責将外部的請求分流,也負責對内部的響應做一些必要的處理。
如果結合mod_cache,則可提高通路速度,适當的減輕網絡流量壓力。
閑話少說,直接拿個例子來:
設本站位址為 www.test.com
ProxyPass /images/ !
ProxyPass /js/ !
ProxyPass /css/ !
ProxyPass /example http://www.example.com/
ProxyPassReverse /example http://www.example.com/
ProxyPass / ajp://127.0.0.1:8009/
ProxyPassReverse / ajp://127.0.0.1:8009/
還是上一篇的例子,ProxyPass易了解,就是轉發url上的請求,而其中的配置順序也是需要遵守。
要禁止轉發的url需要放在一般的請求之前。
對于
http://www.test.com/images/
http://www.test.com/js/
http://www.test.com/css/
的請求是不予轉發的,對于http://www.test.com/example/的請求,會轉發到http://www.example.com。
值得注意的就是ProxyPassReverse的配置了,這是反向代理。
為什麼要在這裡加上這樣的配置?我們來看個例子:
在沒有加這樣的反向代理設定的情況下,通路http://www.test.com/example/a,
如果www.example.com對請求進行了redirect至http://www.example.com/b,
那麼,用戶端就會繞過反向代理,進而通路http://www.test.com/example/b。
如果設定了反向代理,則會在轉交HTTP重定向應答到用戶端之前調整它為http://www.test.com/example/a/b
即是在原請求之後追加上了redirect的路徑。
更多更詳細的關于mod_proxy的描述可以參見手冊:
http://lamp.linux.gov.cn/Apache/ApacheMenu/mod/mod_proxy.html
2 配置 tomcat
2.1 配置 server 的關閉
我們需要在一台機器上跑兩個不同的 tomcat ,需要修改不同的 tomcat 的關閉口,避免出現端口被占用的情況。
其中tomcat6-a用預設值,不修改。
tomcat6-b修改。在tomcat6-b/conf下的 server.xml 中找到 server, 将:
<Server port="8005" shutdown="SHUTDOWN">
改為
<Server port="9005" shutdown="SHUTDOWN">
2.2 配置 Engine
把原來的配置注釋掉,把下面一句去掉注釋。并标明jvmRoute="jvm2"
<Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm2">
以下是原來的配置。
<Engine name="Catalina" defaultHost="localhost">
2.3. 配置 Connector
原來的預設配置。
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
将tomcal6-b 中的 protocol="HTTP/1.1" 的 Connector 端口改為 8081 避免沖突。tomcat6-a 中的保持不變。
protocol="AJP/1.3" 的 Connector 是apache和tomcat連結的關鍵,前台apache就是通過AJP協定與tomcat進行通信的,以完成負載均衡的作用。
也可以用HTTP協定。大家注意它們是如何連接配接通信的,(port="8009")就是連接配接的接口了。
把tomcat6-b的<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> 中的port改成 9009
<proxy balancer://cluster>
#與 tomcat6-a 對應,route與<Engine jvmRoute="jvm1">對應。
BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
#與 tomcat6-b 對應,route與<Engine jvmRoute="jvm2">對應。
BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2
</proxy>
中的端口對應,
tomcat6-a 的ajp端口port:8009
tomcat6-b 的ajp端口port:9009
一定要與上面的一緻。
2.5.配置Cluster(兩個tomcat中都要修改)
原來的配置。
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
修改為以下的代碼:<Receiver port=”XX”/>port也要保證唯一性。
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"? channelSendOptions="6">
<Manager className="org.apache.catalina.ha.session.BackupManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"
mapSendOptions="6"/>
<!--
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
-->
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="5001"
selectorTimeout="100"
maxThreads="6"/>
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*/.gif;.*/.js;.*/.jpg;.*/.png;.*/.htm;.*/.html;.*/.css;.*/.txt;"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
這個設定是主要用以tomcat的叢集。
tomcat叢集各節點通過建立tcp連結來完成Session的拷貝,拷貝有同步和異步兩種模式。
在同步模式下,對用戶端的響應必須在Session拷貝到其他節點完成後進行;異步模式無需等待Session拷貝完成就可響應。
異步模式更高效,但是同步模式可靠性更高。同步異步模式由channelSendOptions參數控制,預設值是8,為異步模式,4是同步模式。
在異步模式下,可以通過加上拷貝确認(Acknowledge)來提高可靠性,此時channelSendOptions設為10。
Manager用來在節點間拷貝Session,預設使用DeltaManager,DeltaManager采用的一種all-to-all的工作方式,
即叢集中的節點會把Session資料向所有其他節點拷貝,而不管其他節點是否部署了目前應用。
當叢集中的節點數量很多并且部署着不同應用時,可以使用BackupManager,BackManager僅向部署了目前應用的節點拷貝Session。
但是到目前為止BackupManager并未經過大規模測試,可靠性不及DeltaManager。
四、啟動服務,測試tomcat自帶的例子
1、測試apache和tomcat協作。
先在每個tomcat中的/webapps/ROOT下的index.jsp下面加上以下的測試代碼部分:
(X代表不同的tomcat的輸出不同的資訊),把index.html删除,以免影響測試效果。
在最後面的加上.即</table></body>之間。
<%
System.out.println("tomcat6 A|B deal with request");
%>
然後再通過http://127.0.0.1來通路一下,就會出現大家熟悉的貓貓。
然後再通過分别通路
http://127.0.0.1:8080
http://127.0.0.1:8081
它們通路的内容和上面的http:// 127.0.0.1是一樣的。
這樣就說明apache和TOMCAT整合成功!
2、測試均衡器
如果在 extra/httpd-vhosts.conf 中配置 沒有設定 lbmethod=bytraffic,将使用預設的 byrequests ,控制配置設定的一共有三種方式,還有一種是 bybusyness 。
通過http://127.0.0.1多次通路,
如果使用的是 byrequests 的配置設定方式,要想看到真正的效果,必須用一些壓力測試工具,可用微軟Microsoft Web Application Stress Tool進行簡單壓力測試,不然你靠不停重新整理是展現不出來的,你隻會在一個tomcat的控制台有輸出結果。
隻用用壓力測試工具模拟大量使用者同時通路,你會發現四個tomcat控制台均有打出控制資訊,說明均衡器工作正常。
而如果配置為 bytraffic 并且tomcat6-a 和 tomcat6-b 設定了 loadfactor=1,則請求會均勻的配置設定給不同的tomcat,很容易測試出來。
如果想對此感興趣,請檢視apache 的文檔并嘗試修改
httpd.conf
----------------------
ProxyRequests Off
<proxy balancer://cluster>
BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2
</proxy>
----------------------
中的 loadfactor 參數和
extra/httpd-vhosts.conf
----------------------
<VirtualHost *:80>
ServerAdmin adminname
ServerName localhost
ServerAlias localhost
ProxyPass / balancer://cluster/ stickysession=jsessionid nofailover=On lbmethod=bytraffic
ProxyPassReverse / balancer://cluster/
</VirtualHost>
----------------------
中的 lbmethod 參數
注意:如果apache 中出現如下錯誤
Encountered too many errors accepting client connections. Possible causes: dynamic address renewal, or incompatible VPN or firewall software. Try using the Win32DisableAcceptEx directive.
編輯httpd.conf 加入
Win32DisableAcceptEx ##加入這行
重新開機apache就解決了。
如果修改後還是不行,任然有錯誤記錄,
cmd下
netsh winsock reset
因為這個錯誤可能與winsock有關,有網友也出現了這個問題,他認為是金山毒霸或者更新精靈修改了WINSOCK導緻的。我沒有安裝但是系統經常自動更新,别的軟體也有,可能會有沖突。
使用此條指令恢複Winsock後,重新開機電腦後這個問題就會解決了。