一、所需软件
Apache/2.2.3
tomcat6.X
jdk1.6
二、安装apache tomcat jdk 并配置环境变量(本次配置在一台机器进行)
三、安装mod_jk,下载mod_jk-1.2.28-httpd-2.2.X.so,并将其复制在etc/httpd/modules下
四、在/etc/httpd/conf下分别建立 mod_jk.conf与workers.properties两个配置文件
mod_jk.conf
JkWorkersFile /etc/httpd/conf/workers.properties
JkLogFile /etc/httpd/logs/mod_jk.log
JkShmFile /etc/httpd/logs/mod_jk.shm
JkLogLevel debug
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
JkRequestLogFormat "%w %V %T"
JkMount /* controller
JkMount /jkstatus/ stat1
JkMount /* controller 把所有的处理都交给tomcat(可自行控制)
workers.properties
worker.list=controller,tomcat1,tomcat2,stat1
#========tomcat1========
worker.tomcat1.type=ajp13
worker.tomcat1.host=localhost
worker.tomcat1.port=8009 #为ajp端口
worker.tomcat1.lbfactor=1
#========tomcat2========
worker.tomcat2.type=ajp13
worker.tomcat2.host=localhost
worker.tomcat2.port=9009#为ajp端口
worker.tomcat2.lbfactor=1
worker.controller.type=lb
worker.controller.sticky_session=true
worker.controller.balance_workers=tomcat1,tomcat2
worker.stat1.type=status
#worker.controller.sticky_session=1
因为在一台服务器故host都为localhost,如不是一台服务器分别写tomcat所在服务器ip地址即可,端口也无需更改。
在/etc/httpd/conf/httpd.conf末尾加上
LoadModule jk_module modules/mod_jk-1.2.28-httpd-2.2.X.so
Include /etc/httpd/conf/mod_jk.conf
五、配置tomcat的server.xml
tomcat1 的 server.xml
将
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
替换为
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
tomcat2的 server.xml
将
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
替换为
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">
修改端口
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="9009" protocol="AJP/1.3" redirectPort="8443" />
之前为8009,修改为9009
<Server port="9005" shutdown="SHUTDOWN">
之前为8005,修改为9005
<Connector port="8090" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
之前为8080,修改为8090
OK。启动tomcat1 tomcat2 与 apache ,至此负载均衡已配置完成。
五、配置机群
将两个tomcat下的webapps的web.xml加上<distributable/>
修改workers.properties中的worker.controller.sticky_session=true ,把true改为false
配置tomcat1 的server.xml
<iCluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">
<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.1"
bind="192.168.1.101"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.1.101"
port="4001"
autoBind="100"
selectorTimeout="5000"
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=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
配置tomcat2的server.xml
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">
<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"
bind="192.168.1.101"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.1.101"
port="4002"
autoBind="100"
selectorTimeout="5000"
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=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
与tomcat1相比也就是改了Receiver 的port 4001为4002(因为是一台机器)
启动tomcat1,完全启动之后,启动tomcat2,然后启动apache。
日志显示
org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor report
信息: ThroughputInterceptor Report[
Tx Msg:1 messages
Sent:0.00 MB (total)
Sent:0.00 MB (application)
Time:0.01 seconds
Tx Speed:0.08 MB/sec (total)
TxSpeed:0.08 MB/sec (application)
Error Msg:0
Rx Msg:2 messages
Rx Speed:0.00 MB/sec (since 1st msg)
Received:0.00 MB]
然后编写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="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>
输入名称与值,提交,打开一个新窗口,输入test.jsp如果能够显示之前的名称和值就表示机群成功(最好多刷新几次)
测试之后没问题,但是把我的项目放进tomcat后,用的是struts2的拦截器做登陆验证,有时候会获取不到session里的值,郁闷。。期待高人回答。。
如果测试不成功,首先确认是否开通开通组播服务,可以用netstate -g 来查看组播状态,也可以在route -e 命令中看到
如果没有执行 route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0 命令来添加,如果需要服务器启动时即开通组播需在/etc/sysconfig/static-routes文件内加入eht0 net 224.0.0.0 netmask 240.0.0.0。
如果还是不成功,netstat -antl |grep 4001 或 netstat -antl |grep 4002 查看监听
下载 http://cvs.apache.org/~fhanik/tomcat-replication.jar tomcat-replication.jar(Linux 执行:wget -c http://cvs.apache.org/~fhanik/tomcat-replication.jar)
java -cp tomcat-replication.jar MCaster 224.0.0.1 45564 Terminal1
java -cp tomcat-replication.jar MCaster 224.0.0.1 45564 Terminal2
查看是否有send数据(我的不知道为什么是乱码。。。。)
如果没数据的话,把防火墙关掉重新执行命令,试试
关闭防火墙 service tptables stop
应该就可以了!