http://blog.csdn.net/dangerous_fire/article/details/6278435
最近要配置tomcat集群,在网上搜了很多文章,但照着步骤一步一步做到最后却无法成功,着使我费了两天的劲查看了apache 和 tomcat的大量文档,才将问题一一解决。为方便自己和新手配置tomcat集群,我将整理好的过程晒一晒,希望可以帮到后来人少走一些弯路。
==================
目标:
使用 apache 和 tomcat 配置一个可以应用的 web 网站,要达到以下要求:
1、 Apache 做为 HttpServer ,后面连接多个 tomcat 应用实例,并进行负载均衡。
2、 为系统设定 Session 超时时间,包括 Apache 和 tomcat
3、 为系统屏蔽文件列表,包括 Apache 和 tomcat
注:本例程以一台机器为例子,即同一台机器上装一个apache和2个Tomcat。
一、前期准备工作:安装用的程序(前提保证已安装了JDK1.5以上的版本)
APAHCE 2.2.8下载:apache_2.2.8-win32-x86-no_ssl.msi
TOMCAT6.0.14下载:apache-tomcat-6.0.14.zip直接解压。
二、安装过程
APAHCE安装目录:D:/Apache。
两个TOMCAT目录:自行解压到(D:/TomcatCluster/)下。
分别为 tomcat6-a,tomcat6-b
三、配置
1、Apache配置
1.1 httpd.conf配置
修改APACHE的配置文件D:/Apache/conf/httpd.conf
这里并没有使用mod_jk.so进行apache和tomcat的链接,从2.X以后apache自身已集成了mod_jk.so的功能。只需简单的把下面几行去掉注释,就相当于以前用mod_jk.so比较繁琐的配置了。
这里主要采用了代理的方法,就这么简单。
将以下Module的注释去掉
LoadModule proxy_module modules/mod_proxy.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 proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
再找到
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
加上index.jsp修改成
<IfModule dir_module>
DirectoryIndex index.html index.jsp
</IfModule>
此处添加index.jsp 主要为了配置完成以后利用index.jsp输出测试信息!
在 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>
上面的两个BalancerMember成员是我们配置的tomcat集群。
1.2 httpd-vhosts.conf设置
接下来进行虚拟主机的设置。
APACHE的虚拟主机设置如下:
首先要修改 conf/httpd.conf
找到
# Virtual hosts
#Include conf/extra/httpd-vhosts.conf
把Include语句注释去掉。改成
# Virtual hosts
Include conf/extra/httpd-vhosts.conf
在文件(extra/httpd-vhosts.conf)最下面加入
<VirtualHost *:80>
ServerAdmin adminname
ServerName localhost
ServerAlias localhost
ProxyPass / balancer://cluster/ stickysession=jsessionid nofailover=On lbmethod=bytraffic
ProxyPassReverse / balancer://cluster/
</VirtualHost>
其中的域名和路径根据你自己情况设置
负载均衡有三种方式,可以通过设置 lbmethod 选择自己需要的方式,详细可查看apache文档
proxy是位于客户端与实际的服务器之间的服务器,一般称为facade server,负责将外部的请求分流,也负责对内部的响应做一些必要的处理。
如果结合mod_cache,则可提高访问速度,适当的减轻网络流量压力。
闲话少说,直接拿个例子来:
设本站地址为 www.test.com
ProxyPass /images/ !
ProxyPass /js/ !
ProxyPass /css/ !
ProxyPass /example http://www.example.com/
ProxyPassReverse /example http://www.example.com/
ProxyPass / ajp://127.0.0.1:8009/
ProxyPassReverse / ajp://127.0.0.1:8009/
还是上一篇的例子,ProxyPass易理解,就是转发url上的请求,而其中的配置顺序也是需要遵守。
要禁止转发的url需要放在一般的请求之前。
对于
http://www.test.com/images/
http://www.test.com/js/
http://www.test.com/css/
的请求是不予转发的,对于http://www.test.com/example/的请求,会转发到http://www.example.com。
值得注意的就是ProxyPassReverse的配置了,这是反向代理。
为什么要在这里加上这样的配置?我们来看个例子:
在没有加这样的反向代理设置的情况下,访问http://www.test.com/example/a,
如果www.example.com对请求进行了redirect至http://www.example.com/b,
那么,客户端就会绕过反向代理,进而访问http://www.test.com/example/b。
如果设置了反向代理,则会在转交HTTP重定向应答到客户端之前调整它为http://www.test.com/example/a/b
即是在原请求之后追加上了redirect的路径。
更多更详细的关于mod_proxy的描述可以参见手册:
http://lamp.linux.gov.cn/Apache/ApacheMenu/mod/mod_proxy.html
2 配置 tomcat
2.1 配置 server 的关闭
我们需要在一台机器上跑两个不同的 tomcat ,需要修改不同的 tomcat 的关闭口,避免出现端口被占用的情况。
其中tomcat6-a用默认值,不修改。
tomcat6-b修改。在tomcat6-b/conf下的 server.xml 中找到 server, 将:
<Server port="8005" shutdown="SHUTDOWN">
改为
<Server port="9005" shutdown="SHUTDOWN">
2.2 配置 Engine
把原来的配置注释掉,把下面一句去掉注释。并标明jvmRoute="jvm2"
<Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm2">
以下是原来的配置。
<Engine name="Catalina" defaultHost="localhost">
2.3. 配置 Connector
原来的默认配置。
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
将tomcal6-b 中的 protocol="HTTP/1.1" 的 Connector 端口改为 8081 避免冲突。tomcat6-a 中的保持不变。
protocol="AJP/1.3" 的 Connector 是apache和tomcat链接的关键,前台apache就是通过AJP协议与tomcat进行通信的,以完成负载均衡的作用。
也可以用HTTP协议。大家注意它们是如何连接通信的,(port="8009")就是连接的接口了。
把tomcat6-b的<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> 中的port改成 9009
<proxy balancer://cluster>
#与 tomcat6-a 对应,route与<Engine jvmRoute="jvm1">对应。
BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
#与 tomcat6-b 对应,route与<Engine jvmRoute="jvm2">对应。
BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2
</proxy>
中的端口对应,
tomcat6-a 的ajp端口port:8009
tomcat6-b 的ajp端口port:9009
一定要与上面的一致。
2.5.配置Cluster(两个tomcat中都要修改)
原来的配置。
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
修改为以下的代码:<Receiver port=”XX”/>port也要保证唯一性。
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"? channelSendOptions="6">
<Manager className="org.apache.catalina.ha.session.BackupManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"
mapSendOptions="6"/>
<!--
<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="5001"
selectorTimeout="100"
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=".*/.gif;.*/.js;.*/.jpg;.*/.png;.*/.htm;.*/.html;.*/.css;.*/.txt;"/>
<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.ClusterSessionListener"/>
</Cluster>
这个设置是主要用以tomcat的集群。
tomcat集群各节点通过建立tcp链接来完成Session的拷贝,拷贝有同步和异步两种模式。
在同步模式下,对客户端的响应必须在Session拷贝到其他节点完成后进行;异步模式无需等待Session拷贝完成就可响应。
异步模式更高效,但是同步模式可靠性更高。同步异步模式由channelSendOptions参数控制,默认值是8,为异步模式,4是同步模式。
在异步模式下,可以通过加上拷贝确认(Acknowledge)来提高可靠性,此时channelSendOptions设为10。
Manager用来在节点间拷贝Session,默认使用DeltaManager,DeltaManager采用的一种all-to-all的工作方式,
即集群中的节点会把Session数据向所有其他节点拷贝,而不管其他节点是否部署了当前应用。
当集群中的节点数量很多并且部署着不同应用时,可以使用BackupManager,BackManager仅向部署了当前应用的节点拷贝Session。
但是到目前为止BackupManager并未经过大规模测试,可靠性不及DeltaManager。
四、启动服务,测试tomcat自带的例子
1、测试apache和tomcat协作。
先在每个tomcat中的/webapps/ROOT下的index.jsp下面加上以下的测试代码部分:
(X代表不同的tomcat的输出不同的信息),把index.html删除,以免影响测试效果。
在最后面的加上.即</table></body>之间。
<%
System.out.println("tomcat6 A|B deal with request");
%>
然后再通过http://127.0.0.1来访问一下,就会出现大家熟悉的猫猫。
然后再通过分别访问
http://127.0.0.1:8080
http://127.0.0.1:8081
它们访问的内容和上面的http:// 127.0.0.1是一样的。
这样就说明apache和TOMCAT整合成功!
2、测试均衡器
如果在 extra/httpd-vhosts.conf 中配置 没有设置 lbmethod=bytraffic,将使用默认的 byrequests ,控制分配的一共有三种方式,还有一种是 bybusyness 。
通过http://127.0.0.1多次访问,
如 果使用的是 byrequests 的分配方式,要想看到真正的效果,必须用一些压力测试工具,可用微软Microsoft Web Application Stress Tool进行简单压力测试,不然你靠不停刷新是体现不出来的,你只会在一个tomcat的控制台有输出结果。
只用用压力测试工具模拟大量用户同时访问,你会发现四个tomcat控制台均有打出控制信息,说明均衡器工作正常。
而如果配置为 bytraffic 并且tomcat6-a 和 tomcat6-b 设置了 loadfactor=1,则请求会均匀的分配给不同的tomcat,很容易测试出来。
如果想对此感兴趣,请查看apache 的文档并尝试修改
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>
----------------------
中的 loadfactor 参数和
extra/httpd-vhosts.conf
----------------------
<VirtualHost *:80>
ServerAdmin adminname
ServerName localhost
ServerAlias localhost
ProxyPass / balancer://cluster/ stickysession=jsessionid nofailover=On lbmethod=bytraffic
ProxyPassReverse / balancer://cluster/
</VirtualHost>
----------------------
中的 lbmethod 参数
注意:如果apache 中出现如下错误
Encountered too many errors accepting client connections. Possible causes: dynamic address renewal, or incompatible VPN or firewall software. Try using the Win32DisableAcceptEx directive.
编辑httpd.conf 加入
Win32DisableAcceptEx ##加入这行
重启apache就解决了。
如果修改后还是不行,任然有错误记录,
cmd下
netsh winsock reset
因为这个错误可能与winsock有关,有网友也出现了这个问题,他认为是金山毒霸或者升级精灵修改了WINSOCK导致的。我没有安装但是系统经常自动更新,别的软件也有,可能会有冲突。
使用此条命令恢复Winsock后,重启电脑后这个问题就会解决了。