在网上看了好多资料,都不完美,没有一篇能按照步骤,配置成功的,故写下自己配置成功的步骤:
配置环境:
系统win8(64位)
JKD1.7 Apache2.4 tomcat7.0
Apache和Tomcat之间的通讯基本有三种方式:
1. Mod_Jk
2. HTTP_Proxy
3. AJP_Proxy
这里主要介绍AJP_Proxy方式,其也是最新、最流行的方式,并且官方的文档也非常全。
步骤1:下载和安装 Tomcat7 和Apache2.4
首先下载Tomcat7 和Apache2.4
1.1 然后安装Apache,安装完成后在IE中输入localhost访问,如果出现It Works则表示Apache安装好了,
1.2 然后下载tomcat7并解压缩到Tomcat1和Tomcat2两个目录中。
1.3 分别启动Tomcat1和Tomcat2看是否可以正常启动。
步骤2:配置Apache2.4
①打开conf/httpd.conf文件,加载以下模块(即把#注释去掉)。
#------------------------start------------------------------------
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
LoadModule speling_module modules/mod_speling.so
LoadModule ssl_module modules/mod_ssl.so
#---------------------end-------------------------------------------
② 如果你想看到小猫页面,
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
在上面的index.html下面添加index.jsp就可以了
③去掉Include conf/extra/httpd-vhosts.conf的注释标记#。
④修改conf/extra/httpd-vhosts.conf文件。
注释掉所有的dummy-host,添加以下内容
<VirtualHost *:80>
ServerAdmin magh@qq.com
ServerName localhost
ServerAlias localhost
ProxyPass / balancer://cluster/ stickysession=jsessionid nofailover=On
ProxyPassReverse / balancer://cluster/
ErrorLog "logs/test-error.log"
CustomLog "logs/test-access.log" common
DocumentRoot "D:/Program Files/Apache Software Foundation/Apache2.4/docs/10.58.178.64" #虚拟目录
</VirtualHost>
上面的balancer://是告诉Apache需要进行负载均衡代理,后面的cluster是集群名,名字可自行定义,再后面*Log为日志引擎,负责日志记录。
⑤ 在conf/httpd.conf文件末尾加反向代理
ProxyRequests Off
<proxy balancer://cluster>
BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2
</proxy>
注意:在实际的项目测试中,以上代码可能是session混乱
如果 tomcat
运行着一个动态站点, 那么上面这种byrequest
的负载均衡调度算法就有很大问题了, 可能刚登录站点再刷新又回到没有登录的状态了, 所以我们就要实现session sticky
- sticky session负载配置a.解释:客户A第一次访问被分配到81端口的tomcat并且登陆了,
- 第二次访问时候访问到了8089,结果就坑了,因为8089的tomcat并没有session。
解决方式有两种,
第一种是session共享,
第二种就是stickysession session粘连,就是说用户一旦访问了某个tomcat,就给他个cookie,让他在后面的请求都访问那个tomcat。
b.session Sticky 可以考虑使用tomcat自己的jsessionid那个cookie,我们这里使用apache的http-header这个模块,由apache来自动生成cookie,配置如下:
补充启用header模块:
- LoadModule headers_module modules/mod_headers.so
- LoadModule headers_module modules/mod_headers.so
(代码如下)
#-------------------------------------begin-----------------------------
#-------------------------------------end----------------------------Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED #新添加的 <Proxy balancer://lbcluster>
#如果tomcat不在一个机器上,端口没有限制
BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2
ProxySet stickysession=ROUTEID #新添加的
</Proxy>
上面的cluster需要与④中的集群名保持一致,Apache通过ajp协议与tomcat进行通信,ip地址与端口号确定了tomcat,loadfactor为负载因子,
Apache按因子比例向tomcat转发请求,route为tomcat配置中的jvmRoute,见章节。
注意:这里的端口(例如:9009)指的tomcat下conf/server.xml文件的JPA的端口:<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
不是<Connector connectionTimeout="20000" port="9080" protocol="HTTP/1.1" redirectPort="18443"/> 这里的端口
测试:启动apache,访问localhost 汇报503错误,这是正常的,因为咱们还没有配置tomcat
⑥ 配置tomcat (以下是转载内容)
6 配置Tomcat
因为是做tomcat集群,本篇以两个tomcat为例介绍,其分别命名为tomcat1、tomcat2。
6.1 配置Server port
用文本编辑器打开${TOMCAT_HOME_1}/conf/server.xml,
找到:<Server port="8005" shutdown="SHUTDOWN">
修改为:<Server port="18005" shutdown="SHUTDOWN">
6.2 配置Connector port
在上一步基础上,继续向下查找、
找到:<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
修改为:<Connector port="18080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="18443" URIEncoding="UTF-8"/>
继续向下搜索
找到:<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
修改为:<Connector port="18009" protocol="AJP/1.3" redirectPort="18443" />
注:这里的port即为Apache通过apj协议与tomcat通信的端口,以实现负载均衡,故此处的端口18009应与4.5章节中端口号对应。
6.3 配置Engine
首先关闭<Engine name="Catalina" defaultHost="localhost">
然后开启<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
注:这里的jvmRoute的值jvm1应与4.5章节中的route相对应。
6.4 配置Cluster
在当前文件中继续向下查找,找到<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>,默认Cluster配置未被开启,这里我们取消注释,使其开启,主要作用是使各tomcat间共享session,据介绍在压力较大的情况下出现了session丢失情况,此段<Cluster />是一下代码的简写,其完整代码如下:
# 同步异步模式由channelSendOptions参数控制,默认值是8,为异步模式,4是同步模式。在异步模式下,可以通过加上拷贝确认(Acknowledge)来提高可靠性,此时channelSendOptions设为10。
|
< 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"
frequency = "500"
dropTime = "3000" />
< Receiver
className = "org.apache.catalina.tribes.transport.nio.NioReceiver"
address = "auto"
port = "15900"
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" />
</ Channel >
# filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
< Valve
className = "org.apache.catalina.ha.tcp.ReplicationValve"
filter = "" />
< Valve
className = "org.apache.catalina.ha.session.JvmRouteBinderValve" />
< Deployer
className = "org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir = "/tmp/war-temp/"
deployDir = "/tmp/war-deploy/"
watchDir = "/tmp/war-listen/"
watchEnabled = "false" />
< ClusterListener
className = "org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener" />
< ClusterListener
className = "org.apache.catalina.ha.session.ClusterSessionListener" />
</ Cluster >
|
上面代码中的<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>及<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>配置是在使用mod_jk并且没有使用sticky sessions或者sticky sessions无法正常工作时的解决方案,我们没有使用mod_jk,也就出现了压力较大session复制失败的情况,因此我们需要将上面的配置去掉这两行,然后替换<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
6.5 配置其他用于集群的tomcat,重复6.1~6.4的操作配置其他tomcat,主要是更改端口号(如:<Server port="9006" shutdown="SHUTDOWN">)
7 测试负载均衡
7.1 测试项目准备
新建一个web项目,取名为cluster_demo;
在项目中新建一个index.jsp页面,在页面body中加入如下内容:
1
2
3
4
|
<%
String sessionid = session.getId();
System.out.println("当前sessionid = " + sessionid);
%>
|
7.2 部署与启动
将上一步建立的测试项目部署到用于集群的tomcat中。
方式一:将项目放置到${TOMCAT_HOME_*}/webapps下;
方式二:在用于集群的tomcat的${TOMCAT_HOME_*}/conf/server.xml中的Host节点下添加
|
< Context
path = "/cluster_demo"
docBase = "D:/apache_tomcat/projects/cluster_demo"
reloadable = "true"
crossContext = "false"
privileged = "true" ></ Context >
|
然后分别启动集群中的tomcat,再启动Apache服务
7.3 并发访问
利用Apache中所带的ab来进行并发访问的模拟测试。
打开命令行窗口,切换至${APACHE_HOME}/bin下
cd ${APACHE_HOME}/bin
ab –n 20 –c 10 http://localhost/cluster_demo/index.jsp
可看到各tomcat控制台中的输出信息,是否分别平均接收了20个请求。
运行结果分别如下图所示,可见两个tomcat平均分担了20个请求:
8 测试session共享
8.1 共享配置
在测试项目的web.xml中,添加<distributable/>元素,这样可以通知tomcat服务器,当前应用需要在急群众的所有节点间实现session共享。
重要:所有session中的对象应是可序列化的,实现java.io.Serializable接口。
8.2 测试准备
在7.1章节基础上,修改index.jsp的内容为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<! DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
< html >
< head >
< title >cluster test - share session</ title >
< meta
http-equiv = "pragma"
content = "no-cache" >
< meta
http-equiv = "cache-control"
content = "no-cache" >
</ head >
< body >
<%
String sessionid = session.getId();
System.out.println("当前sessionid = " + sessionid);
// 如果有新的 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 = "index.jsp"
id = "form_add"
method = "post" >
Key:< input
id = "dataName"
name = "dataName"
type = "text" />
Value:< input
id = "dataValue"
name = "dataValue"
type = "text" />
< input
id = "subBtn"
name = "subBtn"
type = "submit"
value = "提交"
/>
</ form >
</ body >
</ html >
|
8.3 验证测试
重新部署启动后,访问http://localhost/cluster_demo/index.jsp ,在页面上向session中添加一些信息,可看到如下效果,说明session共享咯,不解释。
至此,大功告成!