標籤: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叢集