Apache2 + Tomcat6叢集

來源:互聯網
上載者:User

標籤:blog   http   io   ar   os   使用   sp   java   for   

參考:http://wiki.bsdn.org/pages/viewpage.action?pageId=2621465
http://developer.51cto.com/art/201102/246338.htm
一、軟體準備

Apache 2.2 : http://httpd.apache.org/download.cgi,下載msi安裝程式,選擇no ssl版本
Tomcat 6.0 : http://tomcat.apache.org/download-60.cgi,下載Tomcat 6.0.18 zip檔案     

二、軟體安裝

把Apache安裝為運行在80連接埠的Windows服務,安裝成功後在系統服務列表中可以看到Apache2.2服務。
對於已安裝IIS的機器,在啟動Apache服務之前必須首先停止IIS Admin服務,不然會因為連接埠衝突而無法啟動。
服務啟動後在瀏覽器中輸入http://localhost進行測試,如果能看到一個"It works!"的頁面就代表Apache已經正常工作了。

解壓tomcat zip檔案到兩個檔案夾,分別為t1和t2,以下均以t1和t2代表兩個tomcat伺服器。
配置JAVA_HOME和CLASSPATH系統內容變數,分別啟動t1和t2,確保tomcat可用,然後關閉tomcat。
本文僅為講解配置過程,Apache和tomcat均工作在同一台機器上。
實際部署時沒有任何限制,Apache和單個tomcat可以分別部署在不同的伺服器上。

三、Apache配置

Apache 2.2整合了mod_jk功能,相對於1.3版本,不需要再進行繁瑣的worker.properties配置,配置過程大幅簡化。

首先,在Apache安裝目錄下找到conf/httpd.conf檔案,以文字編輯器開啟。

去掉以下文本前的注釋符(#)以便讓Apache在啟動時自動載入代理(proxy)模組。

LoadModule proxy_module modules/mod_proxy.so 
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so 
LoadModule proxy_balancer_module modules/mod_proxy_balancer.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
向下拉動文檔找到節點,在DirectoryIndex index.html後加上index.jsp,這一步只是為了待會配置完tomcat後能看到小貓首頁,可以不做。

繼續下拉文檔找到Include conf/extra/httpd-vhosts.conf,去掉前面的注釋符。

用文字編輯器開啟conf/extra/httpd-vhosts.conf,配置虛擬網站,在最下面加上

<VirtualHost *:80>  
    ServerAdmin 管理員郵箱 
    ServerName 網域名稱(沒有可用IP地址代替) 
    ServerAlias localhost  
    ProxyPass / balancer://cluster/ stickysession=jsessionid nofailover=On  
    ProxyPassReverse / balancer://cluster/  
    ErrorLog "logs/lbtest-error.log" 
    CustomLog "logs/lbtest-access.log" common 
</VirtualHost>
這裡balancer://是告訴Apache需要進行負載平衡的代理,後面的cluster是叢集名,可以隨意取,兩個日誌引擎ErrorLog負責記錄錯誤,
CustomLog負責記錄所有的http訪問以及返回狀態,日誌名可以自己取,筆者取為lbtest。
httpd-vhosts.conf配置完畢,回到httpd.conf,在文檔最下面加上

ProxyRequests Off  
     <proxy balancer://cluster>  
          BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=node1
          BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=node2
     </proxy>
ProxyRequests Off 是告訴Apache需要使用反向 Proxy(利用Apache進行負載平衡必須使用反向 Proxy,
關於更多負載平衡和反向 Proxy詳情可以參閱筆者另一篇部落格http://zyycaesar.javaeye.com/admin/blogs/293839),
用於配置工作在tomcat叢集中的所有節點,這裡的"cluster"必須與上面的叢集名保持一致。
Apache通過ajp協議與tomcat進行通訊,ip地址和連接埠唯一確定了tomcat節點和配置的ajp接受連接埠。
loadfactor是負載因子,Apache會按負載因子的比例向後端tomcat節點轉寄請求,負載因子越大,對應的tomcat伺服器就會處理越多的請求,
如兩個tomcat都是1,Apache就按1:1的比例轉寄,如果是2和1就按2:1的比例轉寄。
route參數對應後續tomcat配置中的引擎路徑(jvmRoute)。

重啟Apache服務,如果此時訪問http://localhost/將會返回503錯誤,開啟剛才配置的錯誤記錄檔logs/lbtest-error.log,
可以看到錯誤原因是因為後台伺服器沒有響應,因為此時tomcat尚未配置和啟動。

四、Tomcat配置

如果僅僅為了配置一個可用的叢集,Tomcat的配置將會非常簡單。
分別開啟t1和t2的server.xml設定檔,對於t1,盡量採用預設的設定,而對t2作較大改動以避免與t1衝突。
如果t2和t1不在同一台伺服器上運行,對於連接埠就不需做改動。

首先是配置關閉連接埠,找到,t1不變,把t2改為9005。
<Server port="9005" shutdown="SHUTDOWN">

下面配置Connector的連接埠,找到non-SSL HTTP/1.1 Connector,即tomcat單獨工作時的預設Connector,
保留t1預設配置,在8080連接埠偵聽,而把t2設定為在9090連接埠偵聽。
<Connector port="9090" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="9443" />

往下找到AJP 1.3 Connector,,這是tomcat接收從Apache過來的ajp串連請求時使用的連接埠,保留t1預設設定,把t2連接埠改為9009。
注意,這裡的連接埠對應Apache httpd.conf中BalancerMember中配置的ajp串連連接埠。
<!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="9009" protocol="AJP/1.3" redirectPort="9443" />

繼續向下配置引擎,在Engine標籤中加入屬性jvmRoute="node2"(t1中為 jvmRoute="node1")

一、第1種session複製方式
=================================================================================================================
將t1,t2<Engine>標籤中的<cluster>標籤注釋開啟就行了。
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
1).這是預設的session複製方式,即叢集的session複製預設是DeltaManager,是all to all的複製,意思是將叢集下1個tomcat應用下的session
對所有的叢集中的節點進行複製,即使那個節點沒有發布應用。顯然是不好的方式,但這在小規模的叢集下並沒神馬問題。

=================================================================================================================

二、第2種session複製方式
=================================================================================================================
在<Engine>標籤中加入如下代碼:
<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="5000"
                      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|.*\.jpeg|.*\.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>
對於t2,修改Receiver的port為4000 ~ 4100之間的數,並且與t1不重複。
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
這種session複製方式是採用BackupManager,這種適合於大規模的叢集。這種只有session中的值發生改變的時候才會複製session。

=================================================================================================================
如果不是大規模的叢集, 選擇第一種方式就行了。

如果要建立多組Cluster,只需要修改Receiver的address和port就行了。

這裡的jvmRoute對應Apache httpd.conf中BalancerMember中配置的route參數。

這裡的配置是為了可以在叢集中的所有tomcat節點間共用工作階段(Session)。

server.xml的配置修改完畢,下一步需要對具體的應用進行配置。
在webapps目錄下建立test目錄,在test目錄下建立test.jsp檔案,代碼如下:

<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info: 
<% 
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<% 
  out.println("<br> ID " + session.getId()+"<br>");  
  String dataName = request.getParameter("dataName"); 
  if (dataName != null && dataName.length() > 0) { 
     String dataValue = request.getParameter("dataValue"); 
     session.setAttribute(dataName, dataValue); 
  }   
  out.print("<b>Session 列表</b>");   
  Enumeration e = session.getAttributeNames(); 
  while (e.hasMoreElements()) { 
     String name = (String)e.nextElement(); 
     String value = session.getAttribute(name).toString(); 
     out.println( name + " = " + value+"<br>"); 
         System.out.println( name + " = " + value); 
   } 
%>
  <form action="test.jsp" method="POST">
    名稱:<input type=text size=20 name="dataName">
     <br>
    值:<input type=text size=20 name="dataValue">
     <br>
    <input type=submit>
   </form>
</body>
</html>
在test目錄下繼續建立WEB-INF目錄和web.xml,在節點下加入<distributable/>,
這一步非常重要,是為了通知tomcat伺服器,當前應用需要在叢集中的所有節點間實現Session共用。
如果tomcat中的所有應用都需要Session共用,也可以把conf/context.xml中的改為,這樣就不需對所有應用的web.xml再進行單獨配置。

啟動t1,待t1啟動完成後再啟動t2。再次訪問http://localhost,可以看到小貓頁面。
訪問http://localhost/test/test.jsp。可以看到包括伺服器位址,連接埠,sessionid等資訊在內的頁面。

注意這裡的sessionid,與平常的sessionid相比多了小數點和後面的部分,這裡的node1即處理當前請求tomcat伺服器的jvmRoute,
通過這裡可以知道是叢集中的哪一個伺服器處理了當前請求。在文字框中輸入名稱和值,點擊按鈕,資訊就儲存到了Session中,
並且顯示到頁面上。不斷點擊按鈕,可以發現輸入的資訊並未丟失,而且sessionid小數點之前的部分保持不變,
而小數點後面的字元不停的變化,表明是由不同的tomcat伺服器處理了這些請求。
這樣就實現了負載平衡,並且叢集中的不同節點間可以實現會話的共用。
此時如果停止一個tomcat伺服器t2,Apache將會自動把後續請求轉寄到叢集中的其他伺服器即t1。
重啟t2後,Apache會自動偵測到t2的狀態為可用,然後會繼續在t1和t2間進行負載平衡。

如果需要向叢集中增加節點,首先需要對tomcat作類似配置,然後修改Apache httpd.conf,增加BalancerMember,指向新增的tomcat即可。

Apache2 + Tomcat6叢集

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.