Apache+modjk布置tomcat集群
一、版本:
Apache: 2.2.14;
下载地址:http://archive.apache.org/dist/httpd/binaries/win32/
Mod_jk:tomcat-connectors-1.2.37-windows-i386-httpd-2.2.x;
下载地址:http://archive.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/windows/
下载时注意文件名后面的”httpdx.x.x”中的版本号要与apache的版本能对上,否则会因为版本不对导致Apache启动不起来的问题;
Tomcat: 7.0.82
JDK1.7
二、Apache配置:
1、mod_jk.so到Apache安装目录下的modules文件夹下;
2、修改httpd.conf配置文件:
在这个文件的最后增加一行:
include "C:/Cluster/Apache2.2/conf/mod_jk.conf"
3、新增配置文件mod_jk.conf:
文件中输入内容:
#加载mod_jk Module
LoadModule jk_module C:/Cluster/Apache2.2/modules/mod_jk.so
#指定 workers.properties文件路径
JkWorkersFile C:/Cluster/Apache2.2/conf/workers.properties
#指定哪些请求交给tomcat处理,"controller"为在workers.propertise里指定的负载分配控制器名
JkMount /* controller
4、新增配置文件workers.properties:
文件中输入内容:
#server 列表
worker.list=controller,tomcat1,tomcat2
#========tomcat1========
worker.tomcat1.port=8009
worker.tomcat1.host=192.168.1.110
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor=1
worker.tomcat1.socket_timeout=10
worker.tomcat1.socket_keepalive=True
worker.tomcat1.ping_mode=I
worker.tomcat1.ping_timeout=10000
#========tomcat2========
worker.tomcat2.port=8009
worker.tomcat2.host=192.168.1.111
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor=1
worker.tomcat2.socket_timeout=10
worker.tomcat2.socket_keepalive=True
worker.tomcat2.ping_mode=I
worker.tomcat2.ping_timeout=10000
#========controller,负载均衡控制器========
worker.controller.type=lb
#指定此负载平衡器负责的Tomcat应用节点。
worker.controller.balanced_workers=tomcat1,tomcat2
#指定分担请求的tomcat
worker.controller.sticky_session=0
#设为false,则表明需求会话复制。
worker.controller.sticky_session_force=0
上面配置的tomcat1.host, tomcat1.port, tomcat2.host, tomcat2.port分别填写集群的tomcat服务器的ip地址和端口号(端口号要填写ajp协议的端口号);
三、Tomcat配置:
1、安装JDK1.7并配置环境变量JAVA_HOME, JRE_HOME;
2、分别在要集群的服务器上安装tomcat7;
3、修改Server.xml文件:
修改
为:
对于tomcat2也是同样的修改jvmRoute为tomcat2,其他tomcat依次类推;
增加一行:
如果几个tomcat布置在一台机器上,由于端口冲突不能启动,需要修改启动端口,需要修改的地方有:
4、依次启动tomcat的bin目录下的startup.bat文件(linux下启动startup.sh文件)来启动tomcat;
5、在浏览器中打开:http://ip:port 来测试tomcat启动是否正常;
四、测试:
1、新建一个测试的web工程,在web.xml文件中增加一行:
<distributable/>
2、建立测试页面文件index.jsp:
<%@ page contentType="text/html; charset=gbk"%>
<%@ 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.println("<b>Session 列表</b><br>");
System.out.println("============================");
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);
}
%>
</body>
</html>
3、启动Apache,在浏览器中打开:http://localhost:80/test/index.jsp,可以看到Apache会把请求负载到tomcat1和tomcat2上,但是session一直没有改变,说明session在两个tomcat之间进行了同步;
五、Linux上的配置:
实际测试中,按照上面的配置时,在单台win7机器上布置了两个tomcat时是能正常负载和session复制,在两台windows的机器上分别布置tomcat时,负载和session复制也是没问题的,但是分别在两台ubuntu的机器上布置tomcat时,能正常负载,但是session没有复制,每次点击提交按钮刷新页面时会切换tomcat,session都会改变,网上搜索过原因,说时两台机器的时间和时区不同导致的,统一修改了两台机器的时区和时间后仍然不行;
后来在tomcat的配置文件Server.xml中增加集群配置并指定Receiver的ip为本机的ip时,session正确复制了,增加的配置信息如下:
<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">
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="192.168.1.110" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="50"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
</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>
其中的
其中的address修改为当前tomcat运行机器的ip地址即可;
修改完后重启tomcat即可;
配置说明:
1、Manager用来在节点间拷贝Session,默认使用DeltaManager,DeltaManager采用的一种all-to-all的工作方式,即集群中的节点会把Session数据向所有其他节点拷贝,而不管其他节点是否部署了当前应用。当集群中的节点数量很多并且部署着不同应用时,可以使用BackupManager,BackManager仅向部署了当前应用的节点拷贝Session。但是到目前为止BackupManager并未经过大规模测试,可靠性不及DeltaManager。
2、Membership用于发现集群中的其他节点,这里的address用的是组播地址使用同一个组播地址和端口的多个节点同属一个子集群,因此通过自定义组播地址和端口就可将一个大的tomcat集群分成多个子集群。
3、receiver用于各个节点接收其他节点发送的数据,在默认配置下tomcat会从4000-4100间依次选取一个可用的端口进行接收,自定义配置时,如果多个tomcat节点在一台物理服务器上注意要使用不同的端口。
4、Sender用于向其他节点发送数据,具体实现通过Transport配置。
5、Channel 是一个抽象的端口,和socket类似,集群member通过它收发信息。
6、Valve用于在节点向客户端响应前进行检测或进行某些操作,ReplicationValve就是用于检测当前的响应是否涉及Session数据的更新,如果是则启动Session拷贝操作,filter用于过滤请求,如客户端对图片,css,js的请求就不会涉及Session,因此不需检测,默认状态下不进行过滤,监测所有的响应。