1. 准备环境
1.1. Apache
Apache是http服务器,我们利用其对Tomcat进行负载均衡。安装文件为httpd-2.2.25-win32-x86-no_ssl.msi。
下载后直接安装msi即可,能够访问http://localhost/说明安装成功。
1.2. Tomcat
版本为apache-tomcat-7.0.42。
1.3. JK
JK是Tomcat提供给http服务器的插件,安装文件为tomcat-connectors-1.2.37-windows-i386-httpd-2.2.x.zip。
2. 配置过程
2.1. 安装JDK
JDK安装文件为jdk-6u38-windows-x64.exe。
安装目录如下
2.2. 安装Apache
2.3. 安装Tomcat
解压Tomcat
2.4. 配置JDK环境变量
添加jdk环境变量如下
JAVA_HOME=D:\ProgramFiles\Java\jdk1.6.0_38
CLASSPATH= .;%JAVA_HOME%\lib\dt.jar;%%\lib\tools.jar;
2.5. 修改Apache配置
1、修改httpd.conf
我的Apache安装在D:\Program Files (x86)\Apache Software Foundation\Apache2.2,找到conf目录下的httpd.conf,在文件的最后一行添加
Includeconf/mod_jk.conf
2、新建mod_jk.conf文件,内容如下:
LoadModulejk_module modules/mod_jk.so
JkWorkersFileconf/workers.properties
#指定那些请求交给tomcat处理,"controller"为在workers.propertise里指定的负载分配控制器名
JkMount/*.jsp controller
3、将下载的JK插件mod_jk.so复制到Apache安装目录的modules目录下。
4、新建并编辑workers.properties文件,内容如下:
#server
worker.list =controller
#========tomcat115========
worker.tomcat115.port=8009
worker.tomcat115.host=10.1.97.115
worker.tomcat115.type=ajp13
worker.tomcat115.lbfactor= 1
#========tomcat116========
worker.tomcat116.port=8009
worker.tomcat116.host=10.1.97.116
worker.tomcat116.type=ajp13
worker.tomcat116.lbfactor= 1
#========controller,负载均衡控制器========
worker.controller.type=lb
worker.controller.balanced_workers=tomcat115,tomcat116
worker.controller.sticky_session=false
worker.controller.sticky_session_force=1
#worker.controller.sticky_session=1
备注:loadfactor是负载因子,Apache会按负载因子的比例向后端tomcat节点转发请求,负载因子越大,对应的tomcat服务器就会处理越多的请求,如两个tomcat都是1,Apache就按1:1的比例转发,如果是2和1就按2:1的比例转发。
2.6. 配置Tomcat
配置2个Tomcat服务器,将Tomcat解压后复制2份,修改每一份的server.xml配置,将Tomcat115中修改部分如下图:
Tomcat116中以上部分的server.xml为:
AJP13的connector的poat和jvmRoute名称和workers.properties中配置对应。
3. 测试
3.1. 建立测试项目
在test目录下继续新建WEB-INF目录和web.xml,在<web-app>节点下加入<distributable />,这一步非常重要,是为了通知tomcat服务器,
当前应用需要在集群中的所有节点间实现Session共享。如果tomcat中的所有应用都需要Session共享,也可以把conf/context.xml中的
<Context>改为<Contextdistributable="true">,这样就不需对所有应用的web.xml再进行单独配置。
建立test项目,建立test2.jsp,内容如下:
<%@ pagecontentType="text/html; charset=GBK" %>
<%@ pageimport="java.util.*" %>
<html><head><title>ClusterApp 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);
}
%>
<form action="test2.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>
3.2. Session测试
将项目部署到115和116服务器上,然后分别启动Apache和2个Tocmat服务器,这些Tomcat启动顺序随意,然后打开http://localhost/test/test2.jsp,结果如下图:
F5刷新页面,分别出现:
多次刷新页面的sessionID看是同一个ID,说明session是复制成功了。那么session中的存储的东西呢,在输入框中分别输入1、1,2、2,3、3后,显示结果如下图:
以上的测试说明,集群中的session已经共享,每个集群对于同一访问均有相同的session,而且session中存储的变量也复制了。
3.3. 节点插拔测试
插拔意思是应该保证当运行的集群中某节点中关闭或者启动时,集群正常工作并且节点能够正常工作。
关闭Tomcat115,刷新页面,则不断访问Tocmat116,说明节点关闭时运行正常。
从上面可以看出Apache的负载均衡时的算法了,对于每个新来的session,Apache按照节点配置中的lbfactor比重选择访问节点,如果某节点node1不能访问,则寻找下一可访问节点,并且将此node1就在该访问session的访问黑名单中,以后该session的访问直接不考虑node1,即使node1又可以访问了。而新来的session是无黑名单的,如果新的session能够访问到node1了,则会将node1在其他所有session访问的黑名单删除,这样其他session就又能访问node1节点了。
经过以上测试,说明Tomcat集群和负载均衡已经实现了。