一、所需软件
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
应该就可以了!