???????
???????
如上圖所示,主要通過
Apache-Server
作為中轉(zhuǎn)服務(wù)器,實(shí)現(xiàn)多個(gè)
tomcat
服務(wù)器之間的分布式處理,用戶直接請(qǐng)求
Apache-Server
,然后
Apache-Server
會(huì)將請(qǐng)求分發(fā)到具體的
tomcat-server
,之后
tomcat-server
響應(yīng)客戶請(qǐng)求并返回結(jié)果到
Apache-Server
,最后
Apache-Server
返回結(jié)果給用戶
?
文件說明:
mod_jk.conf
主要定義
mod_jk
模塊的位置以及
mod_jk
模塊的連接日志設(shè)置,還有定義
worker.properties
文件的位置。
?
worker.properties?
定義
worker
的參數(shù),主要是連接
tomcat
主機(jī)的地址和端口信息。如果
Tomcat
與
apache
不在同一臺(tái)機(jī)器上,或者需要做多臺(tái)機(jī)器上
tomcat
的負(fù)載均衡只需要更改
workers.properties
文件中的相應(yīng)定義即可。
?
%
APACHE_HOME
%為你的安裝目錄
?
?
環(huán)境說明:
???????
主要使用了一個(gè)
Apache Server
和兩個(gè)
Tomcat
,在同一臺(tái)電腦上進(jìn)行測(cè)試。
?
1.?
準(zhǔn)備軟件
Jdk1.6
下載地址:
http://java.sun.com
tomcat -6.0.29
下載地址:
http://jakarta.apache.org
apache_2.2.4-win32-x86-no_ssl.msi
下載地址:
http://httpd.apache.org/download.cgi
mod_jk-1.2.31-httpd-2.0.52.so?(
主要作用是建立
Apache Server
與
Tomcat
之間的連接
)
下載地址:
http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/
?
???????
說明:
apache-server
安裝完成后,可以在瀏覽器中輸入
http://localhost/
來測(cè)試,如果出現(xiàn)
” It works!”
則表示安裝成功。
2.?
安裝
mod_jk
連接模塊
安裝好
Jdk
、
tomcat
、
apache
后
,
加入
mod_jk
連接模塊,就是把
mod_jk-
1.2.31
-httpd-2.2.3.so
文件
拷貝到%
APACHE_HOME
%
\modules
下,把
jk
模塊的配置放到單獨(dú)的文件中來,在%
APACHE_HOME
%
\conf
目錄新建
mod_jk.conf
、
workers.properties
文件。
?
在
httpd.conf
最后加上:
???????
#?JK?module?settings
Include?conf/mod_jk.conf?
?
說明:以上表示將
mod_jk.conf
配置文件包含進(jìn)來
?
3.?
修改
mod_jk.conf
文件
為了保持
httpd.conf
文件的簡(jiǎn)潔,把
jk
模塊的配置放到單獨(dú)的文件中來。
??????
在
mod_jk.conf
文件中添加以下內(nèi)容:
# Load mod_jk2 module
LoadModule jk_module modules/mod_jk-1.2.31-httpd-2.2.3.so
?
# Where to find workers.properties(
引用
workers
配置文件
)
JkWorkersFile conf/workers.properties
?
# Where to put jk logs(log
文件路徑
)
JkLogFile logs/mod_jk2.log
?
# Set the jk log level [debug/error/info](log
級(jí)別
)
JkLogLevel info
??????
# Select the log format(log
格式
)
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
# JkOptions indicate to send SSL KEY SIZE,
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
?
# JkRequestLogFormat set the request format
JkRequestLogFormat "%w %V %T"
?
# Send JSPs for context / to worker named loadBalancer(URL
轉(zhuǎn)發(fā)配置,匹配的
URL
才轉(zhuǎn)發(fā)到
tomcat
進(jìn)行處理
)
JkMount /*.jsp controller
# JkMount /*.* loadBalancer
??????
4.?
修改
workers.properties
文件
在
workers.properties
文件中添加以下內(nèi)容:
#server?
列表
worker.list =?
controller,tomcat1,tomcat2
?
# tomcat1(ajp13?
端口號(hào),在tomcat下server.xml配置,默認(rèn)8009)
worker.tomcat1.port=8009
#tomcat
的主機(jī)地址,如不為本機(jī),請(qǐng)?zhí)顚?span lang="EN-US">ip地址
worker.tomcat1.host=localhost
worker.tomcat1.type=ajp13
#server
的加權(quán)比重,值越高,分得的請(qǐng)求越多
worker.tomcat1.lbfactor = 1
?
# tomcat2
worker.tomcat2.port=9009
worker.tomcat2.host=localhost
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor = 1
?
# controller(
負(fù)載均衡控制器)
worker.controller.type=lb
#?
指定分擔(dān)請(qǐng)求的tomcat
worker.controller.balanced_workers=tomcat1,tomcat2
#worker.controller.sticky_session=true
說明:此文件配置了
2
個(gè)
tomcat
服務(wù)器進(jìn)行負(fù)載均衡處理
???
5.?
修改
tomcat
配置文件
server.xml
???????
更改其中一個(gè)的設(shè)置打開
tomcat2/conf/server.xml
文件,修改里面所有的端口設(shè)置,將
8
改為
9
,如下:
??????
?

6.?
編寫一個(gè)測(cè)試頁(yè)面
teat1.jsp
???????
建立一個(gè)
test
的
web
應(yīng)用,里面新建一個(gè)
test1.jsp,
內(nèi)容為
<%
@?page?language
=
"
java
"
?contentType
=
"
text/html;?charset=UTF-8
"
????pageEncoding
=
"
UTF-8
"
%>
<!
DOCTYPE?html?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN"?"http://www.w3.org/TR/html4/loose.dtd"
>
<
html
>
<
head
>
<
meta?
http-equiv
="Content-Type"
?content
="text/html;?charset=UTF-8"
>
<
title
>
test1
</
title
>
</
head
>
<
body
>
<%
?

???System.out.println(
"
===========================
"
);

%>
</
body
>
</
html
>
?
7.?
啟動(dòng)服務(wù)器并進(jìn)行測(cè)試
???????
依次啟動(dòng)
apache-server
、
tomcat1
、
tomcat2
,通過
?
http://localhost/test/test1.jsp
?
訪問,查看
tomcat1
的窗口,可以看到打印了一行
"=========="
,再刷新一次,
tomcat2
也打印了一條,再刷新,可以看到請(qǐng)求會(huì)被
tomcat1,tomcat2
輪流處理
,
實(shí)現(xiàn)了負(fù)載均衡
?
三、集群
(session復(fù)制
)
只配置負(fù)載均衡還不行,還要
session
復(fù)制,也就是說其中任何一個(gè)
tomcat
的添加的
session
,是要同步復(fù)制到其它
tomcat
,
?
集群內(nèi)的
tomcat
都有相同的
session
?
1.1?
修改
tomcat1, tomcat2
的
server.xml
文件添加集群內(nèi)容,
tomcat5.5
無需添加,只需要去掉注釋符,
tomcat6.0
需要添加,內(nèi)容如下:
<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="15000"
????????????????waitForAck="true"/>
?
????????????<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>
分別添加以上內(nèi)容后,在
tomcat2
中,修改
tcpListenPort="4001"?
為
4002
?
1.2. Engine
增加
jvmRoute
屬性設(shè)置,
jvmRoute
的值來自于
workers.properties
文件所設(shè)置的服務(wù)器名稱。
<Engine name="Catalina" defaultHost="localhost"?
jvmRoute="tomcat1"
>
?
#server?
列表
worker.list =?
controller,tomcat1,tomcat2
2.?
添加
test.jsp
頁(yè)面
2.1. test.jsp
添加以下內(nèi)容:
<%
@?page?contentType
=
"
text/html;?charset=UTF-8
"
%>
<%
@?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?屬性設(shè)置

??
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
>
?
2.2.?
修改
web.xml
文件,加入
<distributable/>
節(jié)點(diǎn),如下所示:
<?
xml?version="1.0"?encoding="UTF-8"
?>
<
web-app?
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
?xmlns
="http://java.sun.com/xml/ns/javaee"
?xmlns:web
="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
?xsi:schemaLocation
="http://java.sun.com/xml/ns/javaee?http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
?id
="WebApp_ID"
?version
="2.5"
>
??
<
display-name
>
test
</
display-name
>
??
<
distributable
/>
??
<
welcome-file-list
>
????
<
welcome-file
>
index.html
</
welcome-file
>
????
<
welcome-file
>
index.htm
</
welcome-file
>
????
<
welcome-file
>
index.jsp
</
welcome-file
>
????
<
welcome-file
>
default.html
</
welcome-file
>
????
<
welcome-file
>
default.htm
</
welcome-file
>
????
<
welcome-file
>
default.jsp
</
welcome-file
>
??
</
welcome-file-list
>
</
web-app
>
?
測(cè)試步驟如下:
1)????????
啟動(dòng)
apache-server
、
tomcat1
、
tomcat2
2)????????
訪問
http://localhost/test/test.jsp
,輸入名稱:
test0001
、值:
123
并點(diǎn)擊“提交查詢內(nèi)容”按鈕,顯示效果如下:
如上圖所示,
tomcat1
創(chuàng)建了一個(gè)新的
session
,
session
中有屬性
test0001,
值為
123
?
3)????????
關(guān)閉
tomcat1
服務(wù)器,
tomcat1
端口為
8080
,如下圖:
4)????????
在頁(yè)面中再次點(diǎn)擊“提交查詢內(nèi)容”按鈕,效果如下:
????前端頁(yè)面并沒有發(fā)生改變,接下來查看后臺(tái)情況:
?
???
????
如圖所示,可以發(fā)現(xiàn)
session
已成功復(fù)制到
tomcat2
中,以此證明
tomcat
集群已配置成功。
?
?
5)????????
另外來看看不關(guān)閉
tomcat1
服務(wù)器再次提交的情況
???????
如圖所示,請(qǐng)求并沒有轉(zhuǎn)發(fā)到
tomcat2
服務(wù)器,而是再次轉(zhuǎn)回
tomcat1
服務(wù)器,這種情況是由于配置了
jvmRoute
所致,以個(gè)人理解,配置了此屬性后,
apache-server
會(huì)根據(jù)
session
情況來進(jìn)行路由,同一個(gè)
session
會(huì)轉(zhuǎn)發(fā)給同一個(gè)服務(wù)器。
?
?
6)????????
打開一個(gè)新的
IE
窗口,并訪問
http://localhost/test/test.jsp
?????????????
??????????????
?
?????????????
新窗口的請(qǐng)求轉(zhuǎn)發(fā)到了
tomcat2
服務(wù)器,
session
的
id
為
DD9E6C8181653B9BCCF534FC8760B264.tomcat2
,根據(jù)測(cè)試結(jié)果可以說明,在不發(fā)生服務(wù)器關(guān)閉的情況下,每個(gè)
session
會(huì)綁定到同一個(gè)服務(wù)器中,而不會(huì)在服務(wù)器間發(fā)生復(fù)制。