0.1 目標
配置一個可擴展、高可用、有負載均衡和錯誤恢復的 Tomcat 集群
0.2 許可協議
GNU Free Documentation License 允許任意轉載,但請保持本文檔的完整性如有修改,務請通知作者
1. 下載
1.1 Tomcat
1.2 Tomcat 會話復制庫
2. 安裝
2.1 第一個 Tomcat
??? $tar vfxz jakarta-tomcat-4.1.27.tar.gz
??? $cp -R jakarta-tomcat-4.1.27 /www/server/tomcat1
2.2 第二個 Tomcat
# 暫時不安裝,等配置好的一個 Tomcat 后,直接復制得到副本,在副本的基礎上修改得到
2.3 JK2
# 請參考《Linux 下安裝支持 JSP/PHP 的 WEB server》一文編譯.
3. 配置
3.1 Apache 的 JK2 配置文件 workers2.properties
# 這個是 Apache 的 JK2 配置文件,位于 Apache 安裝目錄下的 conf 目錄中,如果原來沒有這個文件,新建一個
# 內容如下
$vi workers2.properties
??? [shm]
??? file=${serverRoot}/logs/shm.file
??? size=1048576
?
??? # First Tomcat
??? [channel.socket:tomcat1]
??? port=11009
??? host=127.0.0.1
?
??? [ajp13:tomcat1]
??? channel=channel.socket:tomcat1
?
??? # Second Tomcat
??? [channel.socket:tomcat2]
??? port=12009
??? host=127.0.0.1
?
??? [ajp13:tomcat2]
??? channel=channel.socket:tomcat2
?
??? # Load Balance
??? [lb:lb1]
??? worker=ajp13:tomcat1
??? worker=ajp13:tomcat2
?
??? # Uri mapping
??? [uri:/*.jsp]
??? group=lb:lb1
3.2 第一個 Tomcat 的 JK2 配置文件 jk2.properties
# 這個是第一個 Tomcat 的 JK2 配置文件,位于第一個 Tomcat 安裝目錄下的 conf 目錄中
# 找到 channelSocket.port=8009
# 取消注釋,并修改為
??? channelSocket.port=11009
3.3 第一個 Tomcat 的配置文件 server.xml
# 這個是第一個 Tomcat 的配置文件,位于第一個 Tomcat 安裝目錄下的 conf 目錄中
# 找到
??? <Server port="8005" shutdown="SHUTDOWN" debug="0">
# 修改為
??? <Server port="11005" shutdown="SHUTDOWN" debug="0">
# 開啟 JK2 AJP connector,關閉其它 connector (也就是把其它的 connector 刪除或注釋掉)
# 修改 JK2 AJP connector 的端口為 11009,修改后的 connector 可能會象下面的樣子
??? <Connector className="org.apache.ajp.tomcat4.Ajp13Connector"
??????? port="11009"
??????? minProcessors="5"
??????? maxProcessors="75"
??????? acceptCount="10"
??????? debug="0"/>
# 為需要集群支持的 webapp 的 context,添加如下manager
??? <Valve className="org.apache.catalina.session.ReplicationValve"
??????? filter=".*\.gif;.*\.jpg;.*\.jpeg;.*\.js"
??????? debug="0"/>
??? <Manager className="org.apache.catalina.session.InMemoryReplicationManager"
??????? debug="10"
??????? printToScreen="true"
??????? saveOnRestart="false"
???? ???maxActiveSessions="-1"
??????? minIdleSwap="-1"
??????? maxIdleSwap="-1"
??????? maxIdleBackup="-1"
??????? pathname="null"
??????? printSessionInfo="true"
??????? checkInterval="10"
??????? expireSessionsOnShutdown="false"
??????? serviceclass="org.apache.catalina.cluster.mcast.McastService"
??????? mcastAddr="228.1.2.3"
??????? mcastPort="45566"
??????? mcastFrequency="500"
??????? mcastDropTime="5000"
??????? tcpListenAddress="auto"
??????? tcpListenPort="4001"
??????? tcpSelectorTimeout="100"
?????? ?tcpThreadCount="2"
??????? useDirtyFlag="true">
??????? </Manager>
3.4 第一個 Tomcat 的啟動腳本 catalina.sh
# 這個是第一個 Tomcat 的 啟動腳本,位于第一個 Tomcat 安裝目錄下的 bin 目錄中
# 添加啟動環境變量如下
??? JAVA_HOME=/usr/java/jdk
????? CATALINA_HOME=/www/server/tomcat1
# 此處的 JAVA_HOME 指向系統實際安裝 JDK 的路徑
# 此處的 CATALINA_HOME 指向第一個 Tomcat 的安裝路徑
3.5 由第一個 Tomcat 復制得到第二個 Tomcat
??? cp -R tomcat1 tomcat2
3.6 第二個 Tomcat 的 JK2 配置文件 jk2.properties
# 參考 3.2
# 修改 channelSocket.port 為
??? channelSocket.port=12009
# 注意和第一個 Tomcat 的差別
3.7 第二個 Tomcat 的配置文件 server.xml
# 參考 3.3
# 修改關閉端口為
??? <Server port="12005" shutdown="SHUTDOWN" debug="0">
# 修改 JK2 AJP connector 的端口為 12009,修改后的 connector 可能會象下面的樣子
??? <Connector className="org.apache.ajp.tomcat4.Ajp13Connector"
??????? port="12009"
??????? minProcessors="5"
??????? maxProcessors="75"
??????? acceptCount="10"
??????? debug="0"/>
# 注意和第一個 Tomcat 的差別
3.8 第二個 Tomcat 的啟動腳本 catalina.sh
# 參考 3.4
# 添加啟動環境變量如下
??? JAVA_HOME=/usr/java/jdk
????? CATALINA_HOME=/www/server/tomcat2
# 此處的 JAVA_HOME 指向系統實際安裝 JDK 的路徑
# 此處的 CATALINA_HOME 指向第二個 Tomcat 的安裝路徑
# 注意和第一個 Tomcat 的差別
4. 完成
4.1 重起 Apache
???? $apache/bin/apachectl graceful
4.2 啟動第一個 Tomcat
???? $tomcat1/bin/catalina.sh start
4.3 啟動第二個 Tomcat
???? $tomcat2/bin/catalina.sh start
5. 參考文獻
http://www-900.ibm.com/developerWorks/cn/java/l-jetspeed/
http://www.filip.net/tomcat/
(申明:本文來源于網絡,摘錄于此,僅為日后方便查看)
Tomcat5.5集群配置
網絡上有好多關于 Tomcat 集群配置的文章,但有些是以 Tomcat 4 為基礎的,有的并不是講的很清楚,自己摸索了半天,試驗成功了,現把簡要過程寫出來,讓你在幾分鐘內體驗一下 Tomcat Cluster 。一、配置環境
下載和安裝 JRE 1.5 最新版 (1.5.06)
下載和安裝 Tomcat 最新版 (5.5.12),假定安裝目錄為 C:\Program Files\Apache Software Foundation\Tomcat 5.5
二、使 Tomcat 集群配置生效
修改 Tomcat 安裝目錄\conf\server.xml ,把 Server/Service/Engine/Host 下的 Cluster 結點前后的注釋符(<!-- 和 -->)刪除,并保存
三、配置第二個 Tomcat 實例
在 C:\Program Files\Apache Software Foundation\ 下新建目錄 Tomcat 5.5 Instance1
將 C:\Program Files\Apache Software Foundation\Tomcat 5.5 目錄下的全部內容復制到 C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1
修改 新實例的服務器配置文件 (C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1\conf\server.xml),把其中的 Server/Service/Connector 的端口更改,以避免和第一個沖突(8080 -> 9080,8009 -> 9009,8443 -> 9443)
修改 Cluster/Receiver 結點的 tcpListenPort 端口(此端口用于 Session 復制),以避免和第一個沖突(4001 -> 4002)
注:Tomcat Cluster 默認使用多播來建立成員關系,即兩個實例的多播的地址和端口一樣,就可以互相認為是同一個 Cluster 的成員。
四、啟動驗證兩個 Tomcat 實例能否正常工作
直接用程序菜單里的 Monitor Tomcat 來啟動第一個實例(或在服務器里啟動)
第二個實例啟動稍微麻煩一些,在 C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1\Bin 下建一個 startup.bat ,用如下 java 命令來啟動:
"C:\Program Files\Java\j實re1.5.0_06\bin\java.exe" -jar .\bootstrap.jar -Dcatalina.home="C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1" -Dcatalina.base="C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1" -Djava.endorsed.dirs="C:\Program Files\Apache Software Foundation\Tomcat 5.5\common\endorsed" -Djava.io.tmpdir="C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1\temp" -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file="C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1\conf\logging.properties" start
看起來挺長,其實主要是第二個實例的安裝目錄太長的緣故,直接執行此批處理就可以啟動第二個實例,如果配置正確,應該可以看到集群管理器啟動,并和第一個實例 ? 建立成員關系的信息。
五、寫一個簡單Web應用,能顯示和設置 Session 屬性值,以供測試
如果有開發工具,新建一個 Web App ,假設為 TomcatDemo
新增 index.jsp ,加入如下代碼:
<%@ page contentType="text/html; charset=UTF-8" import="java.util.*"%>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info: <%out.print(request.getLocalAddr() + " : " + request.getLocalPort());%>
<%
out.println("<br> ID " + session.getId());
// 如果有新的 Session 屬性設置
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);
? }
%>
<form action="index.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>
以上代碼主要是顯示服務器信息和 Session 值,并包含一個 Form ,可以隨時新建一個 Session 屬性值
修改此用應用的 Web.xml ,加入 distributable 屬性,表示 Tomcat 要為此 Web 應用復制 Session ?
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2eehttp://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
? ? <display-name>TomcatDemo</display-name>
? ? <distributable/>
</web-app>
將應用打包成 WAR 文件,分別上現兩個實例的 Tomcat Manager 來部署
(如 果沒有 Java 開發工具,可以直接建立一個 TomcatDemo 的目錄,用 Notepad 將如上的內容復制并保存成 index.jsp,然后在此目錄下新建子目錄 WEB-INF,再用 Notepad 新建一 Web.xml 文件,將上面的代碼復制保存,然后將此目錄壓縮成 Zip 文件,再把后綴改成 .war ,或利用 jar 命令來創建 .war 文件)
六、測試 Tomcat 集群和 Session 復制的是否工作
在 IE 中打開第一個實例中的 TomcatDemo (http://localhost:8080/TomcatDemo),在 Form 里隨便設置一個 Session 屬性,如 MyName = foo
將 IE 地址欄中的地址修改為第二個實例中的 TomcatDemo(http://localhost:9080/TomcatDemo),刷新,就可以看到注意到 SessionID 不變, MyName 的屬性值已有了
同樣,如果在第二實例中設置的值,在第一個實例的頁面中也能看到
注意:必須在同一個 IE 窗口中進行如上測試,以保證是同一個 Session ,如果是兩個窗口,則 Session 可能不同,也互相看不到 Session 復制的結果。
七、其它工作
上述只實現了 Session 復制,而沒有實現 Load Balance(負載均衡),這可以利用 Apache 等來實現,網上有很多相關文章,可能參考)
(http://www.fanqiang.com)
-------------------
實踐中整理出tomcat集群和負載均衡
(一)環境說明
(1)服務器有4臺,一臺安裝apache,三臺安裝tomcat
(2)apache2.0.55、tomcat5.5.15、jk2.0.4、jdk1.5.6或jdk1.4.2
(3)ip配置,一臺安裝apache的ip為192.168.0.88,三臺安裝tomcat的服務器ip分別為192.168.0.1/2/4
(二)安裝過程
(1)在三臺要安裝tomcat的服務器上先安裝jdk
(2)配置jdk的安裝路徑,在環境變量path中加入jdk的bin路徑,新建環境變量JAVA_HOME指向jdk的安裝路徑
(3)在三臺要安裝tomcat的服務器上分別安裝tomcat,調試三個tomcat到能夠正常啟動
(4)tomcat的默認WEB服務端口是8080,默認的模式是單獨服務,我的三個tomcat的WEB服務端口修改為7080/8888/9999
修改位置為tomcat的安裝目錄下的conf/server.xml
修改前的配置為
????<Connector port="8080" maxHttpHeaderSize="8192"
?????????????? maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
?????????????? enableLookups="false" redirectPort="8443" acceptCount="100"
?????????????? connectionTimeout="20000" disableUploadTimeout="true" />
修改后的配置為
????<Connector port="7080" maxHttpHeaderSize="8192"
?????????????? maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
?????????????? enableLookups="false" redirectPort="8443" acceptCount="100"
?????????????? connectionTimeout="20000" disableUploadTimeout="true" />
依次修改每個tomcat的監聽端口(7080/8888/9999)
(5)分別測試每個tomcat的啟動是否正常
http://192.168.0.1:7080
http://192.168.0.2:8888
http://192.168.0.4:9999
(三)負載均衡配置過程
(1)在那臺要安裝apache的服務器上安裝apache2.0.55,我的安裝路徑為默認C:\Program Files\Apache Group\Apache2
(2)安裝后測試apache能否正常啟動,調試到能夠正常啟動http://192.168.0.88
(3)下載jk2.0.4后解壓縮文件
(4)將解壓縮后的目錄中的modules目錄中的mod_jk2.so文件復制到apache的安裝目錄下的modules目錄中,我的為C:\Program Files\Apache Group\Apache2\modules
(5)修改apache的安裝目錄中的conf目錄的配置文件httpd.conf,在文件中加LoadModule模塊配置信息的最后加上一句LoadModule jk2_module modules/mod_jk2.so
(6)分別修改三個tomcat的配置文件conf/server.xml,修改內容如下
修改前
????<!-- An Engine represents the entry point (within Catalina) that processes
???????? every request.??The Engine implementation for Tomcat stand alone
???????? analyzes the HTTP headers included with the request, and passes them
???????? on to the appropriate Host (virtual host). -->
????<!-- You should set jvmRoute to support load-balancing via AJP ie :
????<Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm1">????????
????-->
????????
????<!-- Define the top level container in our container hierarchy -->
????<Engine name="Catalina" defaultHost="localhost">
修改后
????<!-- An Engine represents the entry point (within Catalina) that processes
???????? every request.??The Engine implementation for Tomcat stand alone
???????? analyzes the HTTP headers included with the request, and passes them
???????? on to the appropriate Host (virtual host). -->
????<!-- You should set jvmRoute to support load-balancing via AJP ie :-->
????<Engine name="Standalone" defaultHost="localhost" jvmRoute="tomcat1">????????
????
????????
????<!-- Define the top level container in our container hierarchy
????<Engine name="Catalina" defaultHost="localhost">
????-->
將其中的jvmRoute="jvm1"分別修改為jvmRoute="tomcat1"和jvmRoute="tomcat2"和jvmRoute="tomcat3"
(7)然后重啟三個tomcat,調試能夠正常啟動。
(8)在apache的安裝目錄中的conf目錄下創建文件workers2.propertie,寫入文件內容如下
# fine the communication channel
[channel.socket:192.168.0.1:8009]
info=Ajp13 forwarding over socket
#配置第一個服務器
tomcatId=tomcat1 #要和tomcat的配置文件server.xml中的jvmRoute="tomcat1"名稱一致
debug=0
lb_factor=1 #負載平衡因子,數字越大請求被分配的幾率越高
# Define the communication channel
[channel.socket:192.168.0.2:8009]
info=Ajp13 forwarding over socket
tomcatId=tomcat2
debug=0
lb_factor=1
# Define the communication channel
[channel.socket:192.168.0.4:8009]
info=Ajp13 forwarding over socket
tomcatId=tomcat3
debug=0
lb_factor=1
[status:]
info=Status worker, displays runtime information.??
[uri:/jkstatus.jsp]
info=Display status information and checks the config file for changes.
group=status:
[uri:/*]
info=Map the whole webapp
debug=0
(9)在三個tomcat的安裝目錄中的webapps建立相同的應用,我和應用目錄名為TomcatDemo,在三個應用目錄中建立相同 WEB-INF目錄和頁面index.jsp,index.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>");
??// 如果有新的 Session 屬性設置
??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="index.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>
(10)重啟apache服務器和三個tomcat服務器,到此負載 均衡已配置完成。測試負載均衡先測試apache,訪問http://192.168.0.88/jkstatus.jsp
能否正常訪問,并查詢其中的內容,有三個tomcat的相關配置信息和負載說明,訪問http://192.168.0.88/TomcatDemo/index.jsp看能夠運行,
能運行,則已建立負載均衡。
(四)tomcat集群配置
(1)負載均衡配置的條件下配置tomcat集群
(2)分別修改三個tomcat的配置文件conf/server.xml,修改內容如下
修改前
????????<!--
????????<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
???????????????? managerClassName="org.apache.catalina.cluster.session.DeltaManager"
???????????????? expireSessionsOnShutdown="false"
???????????????? useDirtyFlag="true"
???????????????? notifyListenersOnReplication="true">
????????????<Membership
????????????????className="org.apache.catalina.cluster.mcast.McastService"
????????????????mcastAddr="228.0.0.4"
????????????????mcastPort="45564"
????????????????mcastFrequency="500"
????????????????mcastDropTime="3000"/>
????????????<Receiver
????????????????className="org.apache.catalina.cluster.tcp.ReplicationListener"
????????????????tcpListenAddress="auto"
????????????????tcpListenPort="4001"
????????????????tcpSelectorTimeout="100"
????????????????tcpThreadCount="6"/>
????????????<Sender
????????????????className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
????????????????replicationMode="pooled"
????????????????ackTimeout="5000"/>
????????????<Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
?????????????????? filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
??????????????????
????????????<Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
??????????????????????tempDir="/tmp/war-temp/"
??????????????????????deployDir="/tmp/war-deploy/"
??????????????????????watchDir="/tmp/war-listen/"
??????????????????????watchEnabled="false"/>
??????????????????????
????????????<ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
????????</Cluster>
????????-->??
修改后
????????<!-- modify by whh -->
????????<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
???????????????? managerClassName="org.apache.catalina.cluster.session.DeltaManager"
???????????????? expireSessionsOnShutdown="false"
???????????????? useDirtyFlag="true"
???????????????? notifyListenersOnReplication="true">
????????????<Membership
????????????????className="org.apache.catalina.cluster.mcast.McastService"
????????????????mcastAddr="228.0.0.4"
????????????????mcastPort="45564"
????????????????mcastFrequency="500"
????????????????mcastDropTime="3000"/>
????????????<Receiver
????????????????className="org.apache.catalina.cluster.tcp.ReplicationListener"
????????????????tcpListenAddress="auto"
????????????????tcpListenPort="4001"
????????????????tcpSelectorTimeout="100"
????????????????tcpThreadCount="6"/>
????????????<Sender
????????????????className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
????????????????replicationMode="pooled"
????????????????ackTimeout="5000"/>
????????????<Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
?????????????????? filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
??????????????????
????????????<Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
??????????????????????tempDir="/tmp/war-temp/"
??????????????????????deployDir="/tmp/war-deploy/"
??????????????????????watchDir="/tmp/war-listen/"
??????????????????????watchEnabled="false"/>
??????????????????????
????????????<ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
????????</Cluster>
?????? <!-- modify by whh -->??????
將集群配置選項的注釋放開即可,如上。
(3)重啟三個tomcat。到此tomcat的集群已配置完成。??
??
mail:wanghh2000@163.com
王海輝