征服 Apache + Tomcat

摘自:http://snowolf.iteye.com/blog/743611

征服 Apache + Tomcat

博客分類: Server Architecture
Apache Tomcat原本就是一家,更是一家親!Apache與Tomcat整合,無非是將Apache作爲前端根據請求路徑、端口、代理分發給多個Tomcat,以到達轉發負載均衡的目的!同時,通過Apache和Tomcat相互作用,進行粘性會話會話拷貝構建集羣!這一切的最終結果就是“雲服務”!不要說Session不重要,當下火爆的團購,如果離開Session還能快活多久?如何保證Session同步,仍然是不能迴避的問題!

這裏要說的是基於HTTP和AJP跳轉方式的負載均衡實現,關於JK,由於效率問題一直成爲詬病,並且mod_jk2模塊已經不再被更新了,這裏就不折騰它的複雜配置了!

至於說Apache+Tomcat+SSL,並不是難題!只要完成了Apache+SSL然後配置相應的負載均衡、反向代理等等就可以達到目的,相關Apache+SSL參考征服 Apache + SSL

Ubuntu Server 10.04版本,Apache選用2.2.14,Tomcat選用6.0.24。


相關內容:
征服 Apache + SSL
征服 Apache + SVN
征服 Apache + SVN +  LDAP
征服 Apache + Tomcat


步驟:
  1. 安裝Apache基本模塊
  2. 後臺監控
  3. 負載均衡簡單測試
  4. 配置Tomcat相關模塊(AJP)
  5. 保持Session唯一,粘性會話
  6. Tomcat集羣,Session複製


1.安裝Apache相關模塊
負載均衡需要的主要是代理模塊!
經過幾次Apache配置嘗試,在Ubuntu下配置Apache實在是太容易了。加載什麼模塊、取消什麼模塊兩個命令搞定。

Shell代碼  收藏代碼
  1. #啓用模塊  
  2. sudo a2enmod <model>  
  3. #禁用模塊  
  4. sudo a2dismod <model>  


這裏,我們需要讓Apache提供代理服務,其中又包含基於http、ftp、ajp等等協議的代理功能,同時還需要負載均衡模塊。我們可以通過命令逐個加載:

Shell代碼  收藏代碼
  1. #代理核心模塊  
  2. sudo a2enmod proxy  
  3. #代理AJP模塊  
  4. sudo a2enmod proxy_ajp  
  5. #代理負載均衡模塊  
  6. sudo a2enmod proxy_balancer  
  7. #代理HTTP模塊  
  8. sudo a2enmod proxy_http  
  9. #代理FTP模塊  
  10. sudo a2enmod proxy_ftp  


完成上述操作後,系統會提示重啓Apache!
先不着急重啓,現學現賣,瞭解下Apache的目錄結構。在Ubuntu下配置Apache主要是在/etc/apache2目錄下:

分述:
  • apache2.conf核心配置文件,一般不需要修改!
  • conf.d目錄,裏面包含了一些字符集設置,文檔等設置!
  • dav_svn.authzdav_svn.passwd是前面做SVN時,相關權限、密碼文件。
  • envvars定義了運行時的用戶身份——www-data。
  • httpd.conf是Apache留給我們自己折騰的配置文件,默認爲空。apache2.conf會加載這個文件。
  • ports.conf端口默認配置。apache2.conf會加載這個文件。
  • magic爲mod_mime_magic模塊服務。
  • mods-enabledmods-available mods-enabled會被apache2.conf加載,裏面包含*.load和*.conf文件。*.load文件中是加載相應的模塊(位於/usr/lib/apache2/modules/中),而*.conf中是對應的基本配置。但這些文件其實都是鏈接到mods-available中相應的文件上。當我們通過a2enmod操作時,實際上正是操作了這些軟鏈接。
  • sites-availablesites-enabledmods-enabledmods-available的關係類似,只是其中包含的是站點內容。

羅嗦了一堆,下面配置負載均衡部分。
執行修改:
Shell代碼  收藏代碼
  1. sudo vi /etc/apache2/mods-available/proxy.conf  


上圖紅框中的內容是原始內容,白框中的內容是我新加的部分。
注意紅框中的配置:
Conf代碼  收藏代碼
  1. <Proxy *>  
  2.         AddDefaultCharset off  
  3.         Order deny,allow  
  4.         #Deny from all  
  5.         Allow from localhost ip6-localhost    
  6. </Proxy>  

在默認配置中,Deny from all處於可用狀態。當我們配置其他代理節點時,將導致杜絕訪問!使用Allow from localhost ip6-localhost 限制僅允許本機訪問!
再說,白框中的內容:
Conf代碼  收藏代碼
  1. <Proxy balancer://zlex>  
  2.         BalancerMember http://localhost:8080/  
  3.         BalancerMember http://192.168.49.1:8080/  
  4. </Proxy>  

這裏,我配置了一個負載均衡節點balancer://zlex,其中包含了兩個服務http://localhost:8080/http://192.168.49.1:8080/,一個是虛擬機上的Tomcat、一個是真機上的Tomcat。這裏使用的Http的轉發方式,當然,使用AJP未嘗不可,稍後詳述!
這裏的節點次序會有一個先後關係,Apache會將請求按照FIFO的方式調度順次分配到各個節點上!如果其中有一個節點掛掉,將跳過該節點順次尋找可用節點。
再說代理和反向代理:
Conf代碼  收藏代碼
  1. ProxyPass /zlex balancer://zlex  
  2. ProxyPassReverse /zlex balancer://zlex  

這裏配置,如果要訪問/zlex路徑時,將跳轉到balancer://zlex上,也就是享受負載均衡!

2.後臺監控
我們如何知道某個節點負載多少,響應時間多久,服務是否正常呢?Apache提供了負載均衡監控平臺:http://localhost/balancer-manager。但是,這個服務默認是不存在。
除了用於負載均衡配置、監控的balancer-manager還有http://localhost/server-statushttp://localhost/server-info
我們需要添加info模塊:
Shell代碼  收藏代碼
  1. #系統信息模塊  
  2. sudo a2enmod info  

同時,爲了能夠使用balancer-manager,我們需要配置:
Conf代碼  收藏代碼
  1. <Location /balancer-manager>  
  2.         SetHandler balancer-manager  
  3.         Order Deny,Allow  
  4.         #Deny from all  
  5.         Allow from localhost ip6-localhost  
  6. </Location>  

把這段代碼放到哪?由於它同屬系統信息配置,我把它放到了info.conf中,說白了就是照貓畫虎:
Shell代碼  收藏代碼
  1. sudo vi /etc/apache2/mods-available/info.conf  


注意,這段代碼放到了<IfModule mod_info.c></IfModule>之間!
現在,我們重啓Apache:
Shell代碼  收藏代碼
  1. sudo /etc/init.d/apache2 restart  

來看看管理界面http://localhost/balancer-manager


我們再來看看服務器基本信息http://localhost/server-info


上述兩個服務需要加載info模塊,而服務器狀態(server-status)不需要http://localhost/server-status


3.負載均衡簡單測試
瘋狂訪問http://localhost/zlex,直到手痠眼煩!
我這裏故意使用不同了Tomcat界面,來驗證自己的配置是否生效。更瘋狂的是,我甚至把節點指向了百度、搜狐,來測試負載均衡的效果。如果你細緻觀察,Apache是將請求順次分配到各個節點上的。
如果其中一個節點發生問題(例如,強行關閉一個Tomcat,或配置一個錯誤節點)Apache將會經過幾次嘗試後,繞過這個問題節點,尋找可以成功訪問的節點。如果這個節點恢復正常使用,Apache將在該Tomcat恢復正常工作後大約1分鐘內將該節點標識爲可用!
現在,再看看現在的後臺(http://localhost/balancer-manager)啥樣子:

如果我們控制一個節點的狀態是否可用,該怎麼做:

涉及到負載量,session同步等等,我們最後討論!

4.配置Tomcat相關模塊(AJP)
基於Http協議分發並不複雜,但AJP效果更好!一次詭異事件中,內網訪問正常,外網訪問多次失敗,最後通過AJP方式完美解決了!
在Tomcat中配置AJP也很簡單,修改server.xml開啓AJP模塊:
Shell代碼  收藏代碼
  1. sudo vi /etc/tomcat6/server.xml   

開啓AJP配置:
Xml代碼  收藏代碼
  1. <Connector  port="8009" protocol="AJP/1.3"   
  2.                 URIEncoding="UTF-8"  
  3.                 redirectPort="8443" />  

注意使用的端口port="8009",字符集URIEncoding="UTF-8",這是輸入框、請求字符集亂碼的入口!
接下里就可以通過AJP方式進行節點分發了。修改/etc/apache2/mods-available/proxy.conf
Shell代碼  收藏代碼
  1. sudo vi /etc/apache2/mods-available/proxy.conf    

http改爲ajp,將8080改爲8009
Conf代碼  收藏代碼
  1. <Proxy balancer://zlex>  
  2.         BalancerMember ajp://localhost:8009/  
  3.         BalancerMember ajp://192.168.49.1:8009/  
  4. </Proxy>  

重啓Apache:
Shell代碼  收藏代碼
  1. sudo /etc/init.d/apache2 restart   

再看看管理界面http://localhost/balancer-manager

至此,我們完成了基本負載均衡的基本配置!

/etc/apache2/mods-available/proxy.conf還有一些屬性:
noFailOver是否打開失敗轉移,On|Off,默認爲Off,添加在ProxyPass後面,如:
Conf代碼  收藏代碼
  1. ProxyPass /zlex balancer://zlex  stickySession=JSESSIONID noFailOver=On  

如果這樣配置,當提供給你服務的服務器發生異常,那麼你將一直看着它返回給你503,直到系統恢復正常!

loadfactor表示後臺服務器負載到由Apache發送請求的權值,默認值爲1添加在BalancerMember後面:
Conf代碼  收藏代碼
  1. <Proxy balancer://zlex>  
  2.         BalancerMember ajp://localhost:8009/  
  3.         BalancerMember ajp://192.168.49.1:8009/  
  4. </Proxy>  


可以實現三種策略:
  1. 輪詢均衡策略的配置
  2. 按權重分配均衡策略的配置
  3. 權重請求響應負載均衡策略的配置


5.Session唯一,粘性會話
Apache已經可以輕鬆將內容處理的工作分配給各個Tomcat了!
當然,這還不夠,Session還是個問題!
WHY?

我們來做一系列修改,來檢測Session到底出現了什麼問題!
先來改造Tomcat,修改server.xml
Shell代碼  收藏代碼
  1. sudo vi /etc/tomcat6/server.xml   

修改<Engine />節點,增加jvmRoute屬性:
Xml代碼  收藏代碼
  1. <Engine   
  2.              name="Catalina"   
  3.              defaultHost="localhost"   
  4.              jvmRoute="tomcat1">  

另一個Tomcat設置改爲
Xml代碼  收藏代碼
  1. <Engine   
  2.              name="Catalina"   
  3.              defaultHost="localhost"   
  4.              jvmRoute="tomcat2">  

通過jvmRoute,指定了Tomcat唯一標識!
然後修改/etc/apache2/mods-available/proxy.conf
Shell代碼  收藏代碼
  1. sudo vi /etc/apache2/mods-available/proxy.conf  

如下:
Java代碼  收藏代碼
  1. <Proxy balancer://zlex>  
  2.         BalancerMember ajp://localhost:8009/zlex     route=tomcat1   
  3.         BalancerMember ajp://192.168.49.1:8009/zlex        route=tomcat2   
  4. </Proxy>  
  5.   
  6. ProxyPass /zlex balancer://zlex  
  7. ProxyPassReverse /zlex balancer://zlex  
        <Proxy balancer://zlex>
                BalancerMember ajp://localhost:8009/zlex     route=tomcat1 
                BalancerMember ajp://192.168.49.1:8009/zlex        route=tomcat2 
        </Proxy>

        ProxyPass /zlex balancer://zlex
        ProxyPassReverse /zlex balancer://zlex


這裏需要通過修改route屬性,將Apache與Tomcat關聯起來!
注意,Tomcat中定義的jvmRoute需要與Apache定義的route相對應!
我們來看一下http://localhost/balancer-manager發生了什麼變化:

我們注意到route字段有了新的標識,當然,我們也可以通過這個配置界面修改這些信息,但當前修改不會真的修改/etc/apache2/mods-available/proxy.conf文件,Apache重啓後將丟失。

爲了更細緻的對比進過複雜均衡的結果,這裏增加了zlex應用!主要是監控Session的變化!
只看核心代碼:
Jsp代碼  收藏代碼
  1. <b>當前SessionID:</b>  
  2. <br />  
  3. <%  
  4.         String sessionID = session.getId();  
  5.         out.println(sessionID);  
  6.         System.err.println("sessionID = " + sessionID);  
  7.   
  8.         // 如果有新的 Session 屬性設置  
  9.         String dataName = request.getParameter("dataName");  
  10.         if (dataName != null && !dataName.isEmpty()) {  
  11.                 String dataValue = request.getParameter("dataValue");  
  12.                 session.setAttribute(dataName, dataValue);  
  13.         }  
  14. %>  
  15. <br />  
  16. <br />  
  17. <b>Session屬性列表:</b>  
  18.   
  19. <br />  
  20. <%  
  21.         Enumeration<String> e = (Enumeration<String>) session  
  22.                         .getAttributeNames();  
  23.         while (e.hasMoreElements()) {  
  24.                 String name = e.nextElement();  
  25.                 String value = (String) session.getAttribute(name);  
  26.                 out.println(name + " = " + value + "<br>");  
  27.                 System.err.println(name + " = " + value);  
  28.         }  
  29. %>  
  30. <form method="POST">  
  31. <ul style="list-style-type: none;">  
  32.         <li><label for="dataName">鍵:</label><input size="20" id="dataName"  
  33.                 name="dataName"></li>  
  34.         <li><label for="dataValue">值:</label><input size="20"  
  35.                 id="dataValue" name="dataValue"></li>  
  36.         <li><input type="submit" value="提交" /></li>  
  37. </ul>  
  38. </form>  

將其做成一個名爲zlex的web應用,分別部署到兩個Tomcat上!
然後重啓Apache:
Shell代碼  收藏代碼
  1. sudo /etc/init.d/apache2 restart  

不斷刷新http://localhost/zlex,看看真正的惡魔:
第1次:
第2次:
第3次:
第4次:
仔細觀察,每次請求都按照負載均衡配置的節點次序依次請求到不同的Tomcat上。尤其是當我們通過jvmRouteroute做了綁定之後,信息更加準確。但是,仔細觀察,每次請求的SessionID都是不一樣!對於純Web應用,尤其是依靠SessionID區分唯一用戶的應用,這將是一場噩夢——解決了服務器壓力均衡問題,卻帶來了SessionID不唯一問題!這就需要SessionID綁定,或者說叫做“會話複製”。
如果這時候你在頁面上提交表單,將鍵值對保持在session中,在頁面刷新後,將無法獲得該信息,因爲Seesion丟失了!
接着修改/etc/apache2/mods-available/proxy.conf,讓SeesionID保持唯一:
Shell代碼  收藏代碼
  1. sudo vi /etc/apache2/mods-available/proxy.conf  

增加stickySession屬性:
Conf代碼  收藏代碼
  1. ProxyPass /zlex balancer://zlex  stickySession=JSESSIONID  

stickySession粘性會話,根據這一屬性,瀏覽器將通過cookie綁定SeesionID。如果這個時候再次訪問http://localhost/zlex,你會發現,頁面不會來回跳轉了!
sticky是什麼?
引用
sticky模式
利用負載均衡器的sticky模式的方式把所有同一session的請求都發送到相同的Tomcat節點。這樣不同用戶的請求就被平均分配到集羣中各個tomcat節點上,實現負載均衡的能力。這樣做的缺點是沒有災難恢復的能力。一旦一個節點發生故障,這個節點上所有的session信息全部丟失;
同一用戶同一session只和一個webServer交互,一旦這個webserver發生故障,本次session將丟失,用戶不能繼續使用 !



提交一個Session設定看看http://localhost/zlex

觀察後臺日誌:

再看看返回頁面,這相當於一次頁面刷新,如果正常粘性會話,我們將獲得當前SessionID對應的一切信息:

這說明粘性會話生效了!
我們得到了形如
引用
50DAF14C6CDF8ACFBDC1095A5EE8E2CF.tomcat1
的SessionID。這樣,我們就能知道當前訪問的是哪臺服務器了!
如果,換一個瀏覽器打開該頁面http://localhost/zlex,將會獲得一個新的SessionID,並且,根據Apache中配置的負載均衡節點列表依次訪問下一個節點!
如果這時候負載均衡節點列表中某一節點發生異常,那麼Apache將按照慣例,跳轉該節點,並在該節點恢復正常後約1分鐘內重新將其納入可用節點!

修改剛纔的jsp頁面,看看Http頭中都有些什麼:
Jsp代碼  收藏代碼
  1. <b>Cookie信息:</b>  
  2. <br />  
  3. ${header["cookie"]}  
  4. <br />  
  5. <b>Host信息:</b>  
  6. <br />  
  7. ${header["host"]}  
  8. <br />  


sticky模式的根本在於瀏覽器支持cookie,如果瀏覽器不支持cookie,則需要修改server.xml文件中的<Context />節點,將cookie置爲false,關閉cookie功能,讓jsessionid顯式傳遞!

6.Tomcat集羣,Session複製
經過兩天反覆研究,兩隻互不相認的Tomcat終於在網絡上“資源共享”了——Session複製成功!
關於Tomcat集羣以及Session複製,網上已經有很多很多,但是否真的能用?!爲了確認這一問題,週末還跑到書店翻了翻《Apache Tomcat 高級編程》,參考Clustering/Session Replication HOW-TO(有點小錯誤),經過兩天苦戰,克服種種小問題,終於拿下!

整理概念:
引用

羣集,是包含多個服務器實例的指定集合,這些服務器實例共享相同的應用程序、資源以及配置信息。您可以將不同計算機上的服務器實例分組到一個邏輯羣集中並將其作爲一個單元來管理。您可以使用 DAS 輕鬆控制多機羣集的生命週期。

羣集可以實現水平可伸縮性、負載平衡和故障轉移保護。根據定義,羣集中的所有實例都具有相同的資源和應用程序配置。當羣集中的服務器實例或計算機出現故障時,負載平衡器檢測到該故障,會將通信從出現故障的實例重定向至羣集中的其他實例,並恢復用戶會話狀態。由於羣集中所有實例上的應用程序和資源都相同,因此一個實例可以故障轉移至羣集中的任何其他實例。


引用
Session複製,主要是指集羣環境下,多臺應用服務器之間同步Session,確保Session保持一致,且Session中的內容保持一致,對外透明——看起來就像是一臺應用服務器!
如果其中一臺服務器發生故障,根據負載均衡的原理,Apache會遍歷尋找可用節點,分發請求。與此同時,當前用戶Session不能發生數據丟失,其餘各節點服務器應保證用戶Session數據同步。

Session複製核心內容主要是:
  1. Session內容序列化(serialize),會消耗系統性能。
  2. Session內容通過廣播同步給成員,會造成網絡流量瓶頸,即便是內網瓶頸。


因此,Session複製的這兩個潛在問題,致使複雜均衡節點最多不會超過4個。因爲,當節點數大於4時,整個集羣的吞吐量將不再上升!

爲了搭建Tomcat集羣,我將兩個Tomcat分別部署到兩臺虛擬機上,確保網段一致。(這一步很關鍵,我最初將Tomcat1(192.168.49.132)部署在虛擬機上,將Tomcat2(192.168.49.128)部署在本機上,結果,網絡總有問題,耽誤了很多時間。

由於變換了IP,我需要修改Apache的/etc/apache2/mods-available/proxy.conf文件:
Shell代碼  收藏代碼
  1. sudo vi /etc/apache2/mods-available/proxy.conf   


修改負載均衡節點如下:
Conf代碼  收藏代碼
  1. <Proxy balancer://zlex>  
  2.         BalancerMember ajp://192.168.49.128:8009/zlex        route=tomcat1  
  3.         BalancerMember ajp://192.168.49.132:8009/zlex        route=tomcat2  
  4. </Proxy>  


對於windows系統,不需要考慮網絡問題,廣播地址(這裏用到224.0.0.0240.0.0.0)默認開放,對於linux則需要通過命令開放地址。
Ubuntu上開放廣播地址(eth0網卡):
Shell代碼  收藏代碼
  1. sudo route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0  

然後通過-v參數查看當前開放的廣播地址:
Shell代碼  收藏代碼
  1. route -v  



注意,重啓後,該路由設置將丟失!

在Ubuntu下,可以考慮修改/etc/networks文件!


如果有必要,Windows上開放廣播地址(192.168.49.128本機地址):
Cmd代碼  收藏代碼
  1. route add 224.0.0.0 mask 240.0.0.0 192.168.49.128  

然後通過print參數查看當前開放的廣播地址:
Shell代碼  收藏代碼
  1. route print  



然後,修改tomcat的server.xml文件:
Shell代碼  收藏代碼
  1. sudo vi /etc/tomcat6/server.xml   

<Engine /> 節點中加入如下內容:
Xml代碼  收藏代碼
  1.   <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"  
  2.          channelSendOptions="8">  
  3.   
  4.   <Manager className="org.apache.catalina.ha.session.DeltaManager"  
  5.            expireSessionsOnShutdown="false"  
  6.            notifyListenersOnReplication="true"/>  
  7.   
  8.   <Channel className="org.apache.catalina.tribes.group.GroupChannel">  
  9.     <Membership className="org.apache.catalina.tribes.membership.McastService"  
  10.                 address="224.0.0.0"  
  11.                 port="45564"  
  12.                 frequency="500"  
  13.                 dropTime="3000"/>  
  14.     <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"  
  15.               address="192.168.49.1"  
  16.               port="4000"  
  17.               autoBind="100"  
  18.               selectorTimeout="5000"  
  19.               maxThreads="6"/>  
  20.   
  21.     <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">  
  22.       <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>  
  23.     </Sender>  
  24.     <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>  
  25.     <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>  
  26.   </Channel>  
  27.   
  28.   <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"  
  29.          filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>  
  30.   <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>  
  31.   
  32.   <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>  
  33.   <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>  
  34. </Cluster>   


這裏需要注意<Membership />Receiver<Membership />節點的address屬性是廣播地址;Receiver節點的address屬性是本地綁定地址。當然,默認爲auto。由於我在啓動Tomcat時,Tomcat頻頻將地址指向127.0.0.1,無奈只好使用固定IP。
此外,爲了降低Session複製的成本,Tomcat通過<Valve />節點,以過濾器的方式控制哪些請求可以忽略Session複製:
Xml代碼  收藏代碼
  1. <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"  
  2.        filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>  


同時,在<Host>節點中加入如下內容:
Xml代碼  收藏代碼
  1. <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"  
  2.           tempDir="/tmp/war-temp/"  
  3.           deployDir="/tmp/war-deploy/"  
  4.           watchDir="/tmp/war-listen/"  
  5.           watchEnabled="false"/>  


在Tomcat的官方文檔(Tomcat 6)中,對於<Deployer  />節點的部署位置是錯誤的,通過觀察Tomcat啓動日誌,確認該節點應當不屬於<Host />節點中!

注意:Tomcat 6與Tomcat5在上述節點中使用的類包(包中名稱由cluster變化爲ha)有所不同,且結構有所調整。

先別急着重啓,我們需要修改應用中的web.xml文件,將<distributable />節點部署到<web-app />節點中,開啓分佈式服務:


注意:如果沒有設置該節點,SessionID將不能保持同步,不同的服務器將各自建立獨立的SessionID!

監控Tomcat日誌:
Shell代碼  收藏代碼
  1. tail -f /var/lib/tomcat6/logs/catalina.out   

然後重啓Tomcat1:
Shell代碼  收藏代碼
  1. sudo /etc/init.d/tomcat6 restart  

觀察日誌:

注意兩處紅框:
第一處,Cluster啓動,並綁定192.168.49.132:4000上,進行TCP通訊,並等待其它成員(Member)。
第二處,在管理器中註冊[b]/zlex
,綁定JvmRouteBinderValve。[/b]

至此,說明集羣設置已經生效,但不能說明集羣配置成功!

接着我們啓動Tomcat2,觀察其日誌:

Cluster啓動,並綁定192.168.49.128:4000上並發現成員[b]192.168.49.132![/b]
再看Tomcat1的日誌:

Tomcat1發現其成員Tomcat2!這說明TCP通訊已建立,Tomcat成員可以進行Session同步!
同時,Tomcat成員直接會每隔一個時間段相互偵測/驗證其他成員是否正常:


現在,開始訪問http://localhost/zlex,並不斷刷新當前頁面:

除了兩處標識主機來源的tomcatX不同外,session是完全一致的!
提交一次修改,並不斷刷新當前頁:

如果仔細觀察,當前SessionID在不斷交替變化,這說明負載均衡在起作用!
我們再來看看2個Tomcat後臺日誌都做了什麼!
Tomcat1:

Tomcat2:
兩隻貓都打印了相同的內容(a=1)不同的細節在於,sessionID帶有服務器標識!

如果我們強行關閉Tomcat2:
首先,Tomcat1會很快偵測到Tomcat2離線,因爲這是TCP通訊,成員之間很容易檢測到其他成員是否離線!Tomcat1後臺日誌如下:

其次,Apache會偵測到Tomcat2發生異常,將其餘請求轉交給其他節點,即交由Tomcat1處理!
繼續刷新http://localhost/zlex當前頁面,耐心等待幾秒。你會發現,即便再次刷新頁面,sessionID仍舊綁定在標識tomcat1服務器上。
然後,我們恢復Tomcat2服務,Tomcat1會馬上偵測到Tomcat2已經恢復正常:

最後,我們再次刷新當前頁,Apache已經將請求分發給Tomcat2了,從後臺日誌可以看到session信息會很快被同步了!

如果帶有tomcatX標識的sessionID有很多不便之處,可以關閉粘性會話。簡單的講,就是取消Tomcat中[b]server.xml<Engine/ >節點的jvmRoute屬性![/b]然後,重啓tomcat、apache!

頁面提交一個b=3

左邊爲Tomcat1,右邊爲Tomcat2!SessionID一致!

除了上述幾種方案外,還有Terracotta模式。一種第三方集羣組件,2009年收購了緩存組件EhCache,可以結合Tomcat、JBoss等多種服務器,提供多種負載均衡、集羣等功能實現,且當負載均衡節點超過8個時,仍然能夠保持集羣吞吐量的線性增長。
Eclipse插件地址:
http://download.terracotta.org/eclipse/update
下載地址:
http://www.terracotta.org/dl/oss-download-catalog

至此,Apache + Tomcat成功完成,征服Apache系列暫告一段落!
作爲開博以來的第100帖,算是很成功了!

測試應用見附件!



相關內容:
征服 Apache + SSL
征服 Apache + SVN
征服 Apache + SVN +  LDAP
征服 Apache + Tomcat
  • 大小: 60 KB
  • 大小: 64.9 KB
  • 大小: 48.5 KB
  • 大小: 92.6 KB
  • 大小: 21.6 KB
  • 大小: 49.4 KB
  • 大小: 34.9 KB
  • 大小: 91.9 KB
  • 大小: 95.7 KB
  • 大小: 77 KB
  • 大小: 16.8 KB
  • 大小: 18.4 KB
  • 大小: 16.5 KB
  • 大小: 19.2 KB
  • 大小: 19.5 KB
  • 大小: 12.8 KB
  • 大小: 18.1 KB
  • 大小: 12.2 KB
  • 大小: 25.7 KB
  • 大小: 56.6 KB
  • 大小: 228.7 KB
  • 大小: 131.2 KB
  • 大小: 42 KB
  • 大小: 122.5 KB
  • 大小: 31 KB
  • 大小: 32 KB
  • 大小: 32 KB
  • 大小: 13.9 KB
  • 大小: 19.1 KB
  • 大小: 61.6 KB
  • 大小: 25.7 KB
  • 大小: 33.2 KB
  • 大小: 32.7 KB
  • 大小: 26.2 KB
  • 大小: 58.9 KB

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章