本文基本參考自
輕松實現Apache,Tomcat集群和負載均衡
,經由實操經歷記錄而成,碰到些出入,以及個別地方依據個人的習慣,所以在一定程度上未能保持原文的完整性,還望原著者海涵。
因原文中有較多的貼圖,如若各位讀者一時不想親自動手而直想看到配置效果,可查看原文。
一:軟件環境
?? 1. Apache: apache 2.0.55 (由
http://httpd.apache.org/
進入下載)(
點擊下載apache 2.0.55
)
?? 2. Tomcat: Tomcat 5.5.25 (由
http://tomcat.apache.org/
進入下載)(
點擊下載Tomcat 5.5.25 zip版
)
?? 3. mod_jk: 在頁面
http://tomcat.apache.org/
?? Download 標題下找到 Tomcat Connectors 鏈接進入(
點擊下載mod_jk-apache-2.0.55.so
),看起來像是個Unix/Linux下的動態庫,實際應是個Win32 的 DLL 動態庫,大概是為保持不同平臺配置的一致性,才用了這個擴展名。
二:負載均衡
用Apache進行分流,把請求按照權重以及當時負荷分tomcat1,tomcat2...去處理
1. 安裝apache,tomcat
?? 我把Apache安裝在D:\Apache Group\Apache2
解壓兩分Tomcat, 分別在 D:\Apache Group\Tomcat5_1,D:\Apache Group\Tomcat5_2
?? 如果把不同版本的Tomcat進行集群,目錄就可用Tomcat4_3(版本為4.x的第三個tomcat服務器),Tomcat6_4(版本為6.x的第三個tomcat服務器),這是Unmi本人的習慣。
2.修改Apache配置文件http.conf
?? 在apache安裝目錄下conf目錄中找到http.conf,在文件最后加上下面一句話就可以了
??
include conf\mod_jk.conf
3. http.conf 同目錄下新建mod_jk.conf文件
,內容如下
?
-
??
-
LoadModule jk_module modules/mod_jk-apache-2.0.55.so ??
-
??
-
-
JkWorkersFile conf/workers.properties ??
-
??
-
??
-
JkMount /*.jsp controller??
?
如果還要指定*.do也進行分流就再加一行
JkMount /*.do controller
如果你想對所有的請求進行分流只需要寫成
JkMount /* controller
4. 在http.conf同目錄下新建 workers.properties文件
,內容如下
?
-
worker.list = controller,tomcat1,tomcat2??
??
-
??
-
worker.tomcat1.port=8009
??
-
worker.tomcat1.host=localhost??
??
-
worker.tomcat1.type=ajp13 ??
-
worker.tomcat1.lbfactor = 1???
??
-
??
-
??
-
worker.tomcat2.port=8109???????
??
-
worker.tomcat2.host=localhost??
??
-
worker.tomcat2.type=ajp13 ??
-
worker.tomcat2.lbfactor = 2???
??
-
??
-
??
-
worker.controller.type=lb ??
-
worker.controller.balanced_workers=tomcat1,tomcat2???
??
-
worker.controller.sticky_session=1??
?
5. 修改tomcat配置文件server.xml
如果你是水平集群,即在不同電腦上安裝tomcat,tomcat的安裝數量為一個,可以不必修改tomcat配置文件
.我這里是在同一臺電腦上安裝兩個tomcat,實現的是垂直集群方式,所以必須修改其中一個的設置,以避免端口沖突,按照參考文章是把原來以9開頭的端口號改為以9開頭端口號,但是在我機器上如果以9開頭的端口號,例如9080、9082會與我的WebSphere Application Server配置沖突,所以我這里采取的策略是把原來端口號的第三位改為1,如8080改為8180。
打開tomcat2/conf/server.xml文件
1) 將關閉Tomcat的監聽端口改成由8005改為8105
即把
<Server port="
8005
" shutdown="SHUTDOWN">
改為
<Server port="
8105
" shutdown="SHUTDOWN">
2) 把http服務端口號由8080改為8180
找到
<!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
??? <CONNECTOR port="
8080
"
把這里的8080改為
8180
3) 把AJP端口號由8009改為8109
找到
<!-- Define an AJP 1.3 Connector on port 8009 -->
??? <CONNECTOR port="
8009
"
把這里的8009改為
8109
4) 把 HTTP 代理端口從8082改為8182(
這個配置默認是被注釋掉的,可跳過這一步
)
找到
<CONNECTOR port="
8082
"
把這里的8082改為
8182
5) 編寫一個測試 jsp
建立一個目錄TestCluster,里面新建一個test.jsp,內容為
?
-
<
% ??
-
??? System.out.println("==========================="); ??
-
%
>
??
把TestCluster放到tomcat1,tomcat2的webapps下
6) 啟動apache,tomcat1,tomcat2,進行測試
通過
http://localhost/TestCluster/test.jsp
訪問,多刷新幾次頁面,查看Tomcat1和Tomcat2的窗口,你將可以看到打印了一行行"===========================",并且從統計上來說,大約在tomcat2打印的數量是在Tomcat1中的兩倍,可以看到請求會被tomcat1,tomcat2按照不同的權重分流處理,實現了負載均衡。
作下面的集群配置,請在workers.properties把tomcat1和tomcat2的權重改為一樣的,使請求較平均分配,將有便于看到實驗的效果。
?
三:配置集群
只配置負載均衡還不行,還要session復制,也就是說其中任何一個tomcat的添加的session,是要同步復制到其它tomcat, 集群內的tomcat都有相同的session
1. 修改tomcat1, tomcat2的server.xml,將集群部分配置
,即對<Cluster>節點的在注釋符刪掉,并將tomcat2的4001端口改為4002,以避免與tomcat沖突,當然,如果是兩臺電腦,是不用改端口的,去掉注釋符即可
即取消對如下處
1
??
<
Cluster
className
="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
2
??????????? managerClassName
="org.apache.catalina.cluster.session.DeltaManager"
3
??????????? expireSessionsOnShutdown
="false"
4
??
5
?????? <ClusterListener className
="org.apache.catalina.cluster.session.ClusterSessionListener"
/>
6
??
</
Cluster
>
前后的注釋標記<!-- -->,啟用該項配置,實現服務器間的Session復制。
2. 為 Tomcat1和 Tomcat2 增加 jvmRoute
(
先跳過這一步,有精力可以試驗一下
)
在 Tomcat1 和 Tomcat2 的 server.xml 文件,找到
<ENGINE name="Catalina" defaultHost="localhost">
分別改為
<ENGINE name="Catalina" defaultHost="localhost"
jvmRoute="tomcat1"
>
和
<ENGINE name="Catalina" defaultHost="localhost"
jvmRoute="tomcat2"
>
然而實際我配置的時候還不能加jvmRoute屬性,配置了反而有問題。
刷新瀏覽器窗口總是在某一個tomcat控制臺輸出形如
SessionID:154678FA6D4D0ABD57658B750E7A3532.tomcat1
(在tomcat1窗口)
或者
SessionID:3800571A532AECEA7280F45361861AD4.tomcat2
(在tomcat2窗口)
由控制臺打印的結果可以看出,SessionID在哪個tomcat上產生,那么后續該會話的請求將總是會這個tomcat來處理。
并且注意到SessionID的形式比通常情況多了一個后綴.tomcat1或.tomcat2,還搞不清楚是為什么。
配置時請視實際情況而取舍。
3. 修改測試項目 TestCluster
修改test.jsp,內容如下
?
?
-
<
%@ page
contentType
=
"text/html; charset=GBK"
%
>
??
-
<
%@ page
import
=
"java.util.*"
%
>
??
-
<
html
>
<
head
>
<
title
>
Cluster App Test
</
title
>
</
head
>
??
-
<
body
>
??
-
<
% ??
-
??? System.out.println("SessionID:"?? + session.getId()); ??
-
%
>
??
-
Server Info: ??
-
<
% ??
-
out.println(request.getServerName() + " : " + request.getServerPort()+"
<
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
>
<
br
>
");?? ??
-
?? 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
>
??
?
4. 配置Session復制
在TestCluster目錄下新建WEB-INF目錄,WEB-INF下新建web.xml,內容如下
-
<
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/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version
=
"2.4"
>
??? ??
-
???????
<
display-name
>
TomcatClusterDemo
</
display-name
>
??? ??
-
???????
<
distributable
/>
??? ??
-
<
web-app
>
??
也就是在需要集群的應用的web.xml中加上屬性,表明該應用可多應用分流處理,能進行Session的復制
把TestCluster復制到Tomcat1、Tomcat2的webapps目錄下,重啟apache,tomcat1,tomcat2
5. 測試Session的復制
通過
http://localhost/TestCluster/test.jsp
訪問,輸入名稱為 name, 值為 Unmi,提交查詢,多刷新幾次瀏覽器窗口,你將會看到在兩個Tomcat窗口都打印出相同的SessionID及其中的值,并且每次刷新后打印的結果都一樣的。
如果不為應用的web.xml加上 ,同樣測試上面那個test.jsp頁面,每次刷新分流到不同的tomcat上都會產生不一樣的SessionID,在同一個tomcat上也是間隔出現不同的sessionID。
更切身的體驗是一定要自己動手配置一遍,并仔細觀察兩個tomcat的控制上的輸出。因本文是參考
輕松實現Apache,Tomcat集群和負載均衡
的實踐經歷,該本中有較多的貼圖。
后記:
用 WebSphere Application Server ND 版配置過垂直和水平集群,但是自己試驗集群環境下的應用卻不想搬弄這個龐然大物。眼下急于想體驗的就是 Quartz 如何適應集群環境,問題的焦點就是:Quartz 定時任務隨 Web 應用啟動,而 Web 應用部署在集群環境中,如何保證同一時刻只有一個同名的任務實例在跑。
所以會考慮用Apache+Tomcat配置一個輕量級的WEB應用集群,一般進行HTTP分流都是使用Apache,包括WAS集群也是,很少用IIS的。雖然單純的用Tomcat的balancer應用也能配置進行負載分流,但那個性能應該好不到哪兒去。
用Apache+Tomcat配置的Web應用集群就是部署起來麻煩些,總是要保持雙份的應用拷貝,WAS集群則不需要,不知道Jboss做WEB應用集群是怎么樣一種情況。
好了,下面要進行該做的事情了,最后也希望能寫個工具能完成從下載到安裝配置,啟動,停止,重啟的全自動化,以及界面的人性化。
參考資料:1.
輕松實現Apache,Tomcat集群和負載均衡
????????? 2.
apache+tomcat集群實踐
(與上面方法有些異樣的配置方式)
????????? 3.
Tomcat集群與負載均衡
(關于集群與負載均衡的解釋)
????????? 4.
怎樣配制集群/Session復制
(Tomcat5自帶文檔的中文翻譯)
????????? 5.
怎樣配置負載均衡
(Tomcat5自帶文檔的中文翻譯)