???????
???????
如上圖所示,主要通過
Apache-Server
作為中轉服務器,實現多個
tomcat
服務器之間的分布式處理,用戶直接請求
Apache-Server
,然后
Apache-Server
會將請求分發到具體的
tomcat-server
,之后
tomcat-server
響應客戶請求并返回結果到
Apache-Server
,最后
Apache-Server
返回結果給用戶
?
文件說明:
mod_jk.conf
主要定義
mod_jk
模塊的位置以及
mod_jk
模塊的連接日志設置,還有定義
worker.properties
文件的位置。
?
worker.properties?
定義
worker
的參數,主要是連接
tomcat
主機的地址和端口信息。如果
Tomcat
與
apache
不在同一臺機器上,或者需要做多臺機器上
tomcat
的負載均衡只需要更改
workers.properties
文件中的相應定義即可。
?
%
APACHE_HOME
%為你的安裝目錄
?
?
環境說明:
???????
主要使用了一個
Apache Server
和兩個
Tomcat
,在同一臺電腦上進行測試。
?
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/
來測試,如果出現
” It works!”
則表示安裝成功。
2.?
安裝
mod_jk
連接模塊
安裝好
Jdk
、
tomcat
、
apache
后
,
加入
mod_jk
連接模塊,就是把
mod_jk-
1.2.31
-httpd-2.2.3.so
文件
拷貝到%
APACHE_HOME
%
\modules
下,把
jk
模塊的配置放到單獨的文件中來,在%
APACHE_HOME
%
\conf
目錄新建
mod_jk.conf
、
workers.properties
文件。
?
在
httpd.conf
最后加上:
???????
#?JK?module?settings
Include?conf/mod_jk.conf?
?
說明:以上表示將
mod_jk.conf
配置文件包含進來
?
3.?
修改
mod_jk.conf
文件
為了保持
httpd.conf
文件的簡潔,把
jk
模塊的配置放到單獨的文件中來。
??????
在
mod_jk.conf
文件中添加以下內容:
# 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
級別
)
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
轉發配置,匹配的
URL
才轉發到
tomcat
進行處理
)
JkMount /*.jsp controller
# JkMount /*.* loadBalancer
??????
4.?
修改
workers.properties
文件
在
workers.properties
文件中添加以下內容:
#server?
列表
worker.list =?
controller,tomcat1,tomcat2
?
# tomcat1(ajp13?
端口號,在tomcat下server.xml配置,默認8009)
worker.tomcat1.port=8009
#tomcat
的主機地址,如不為本機,請填寫ip地址
worker.tomcat1.host=localhost
worker.tomcat1.type=ajp13
#server
的加權比重,值越高,分得的請求越多
worker.tomcat1.lbfactor = 1
?
# tomcat2
worker.tomcat2.port=9009
worker.tomcat2.host=localhost
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor = 1
?
# controller(
負載均衡控制器)
worker.controller.type=lb
#?
指定分擔請求的tomcat
worker.controller.balanced_workers=tomcat1,tomcat2
#worker.controller.sticky_session=true
說明:此文件配置了
2
個
tomcat
服務器進行負載均衡處理
???
5.?
修改
tomcat
配置文件
server.xml
???????
更改其中一個的設置打開
tomcat2/conf/server.xml
文件,修改里面所有的端口設置,將
8
改為
9
,如下:
??????
?

6.?
編寫一個測試頁面
teat1.jsp
???????
建立一個
test
的
web
應用,里面新建一個
test1.jsp,
內容為
<%
@?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.?
啟動服務器并進行測試
???????
依次啟動
apache-server
、
tomcat1
、
tomcat2
,通過
?
http://localhost/test/test1.jsp
?
訪問,查看
tomcat1
的窗口,可以看到打印了一行
"=========="
,再刷新一次,
tomcat2
也打印了一條,再刷新,可以看到請求會被
tomcat1,tomcat2
輪流處理
,
實現了負載均衡
?
三、集群
(session復制
)
只配置負載均衡還不行,還要
session
復制,也就是說其中任何一個
tomcat
的添加的
session
,是要同步復制到其它
tomcat
,
?
集群內的
tomcat
都有相同的
session
?
1.1?
修改
tomcat1, tomcat2
的
server.xml
文件添加集群內容,
tomcat5.5
無需添加,只需要去掉注釋符,
tomcat6.0
需要添加,內容如下:
<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>
分別添加以上內容后,在
tomcat2
中,修改
tcpListenPort="4001"?
為
4002
?
1.2. Engine
增加
jvmRoute
屬性設置,
jvmRoute
的值來自于
workers.properties
文件所設置的服務器名稱。
<Engine name="Catalina" defaultHost="localhost"?
jvmRoute="tomcat1"
>
?
#server?
列表
worker.list =?
controller,tomcat1,tomcat2
2.?
添加
test.jsp
頁面
2.1. test.jsp
添加以下內容:
<%
@?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?屬性設置

??
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/>
節點,如下所示:
<?
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
>
?
測試步驟如下:
1)????????
啟動
apache-server
、
tomcat1
、
tomcat2
2)????????
訪問
http://localhost/test/test.jsp
,輸入名稱:
test0001
、值:
123
并點擊“提交查詢內容”按鈕,顯示效果如下:
如上圖所示,
tomcat1
創建了一個新的
session
,
session
中有屬性
test0001,
值為
123
?
3)????????
關閉
tomcat1
服務器,
tomcat1
端口為
8080
,如下圖:
4)????????
在頁面中再次點擊“提交查詢內容”按鈕,效果如下:
????前端頁面并沒有發生改變,接下來查看后臺情況:
?
???
????
如圖所示,可以發現
session
已成功復制到
tomcat2
中,以此證明
tomcat
集群已配置成功。
?
?
5)????????
另外來看看不關閉
tomcat1
服務器再次提交的情況
???????
如圖所示,請求并沒有轉發到
tomcat2
服務器,而是再次轉回
tomcat1
服務器,這種情況是由于配置了
jvmRoute
所致,以個人理解,配置了此屬性后,
apache-server
會根據
session
情況來進行路由,同一個
session
會轉發給同一個服務器。
?
?
6)????????
打開一個新的
IE
窗口,并訪問
http://localhost/test/test.jsp
?????????????
??????????????
?
?????????????
新窗口的請求轉發到了
tomcat2
服務器,
session
的
id
為
DD9E6C8181653B9BCCF534FC8760B264.tomcat2
,根據測試結果可以說明,在不發生服務器關閉的情況下,每個
session
會綁定到同一個服務器中,而不會在服務器間發生復制。