1前言
本文讲述了如何在Windows和Linux下进行Apahce+Tomcat集群的安装配置。
Windows下Tomcat 集群的安装配置与Linux下稍有区别,本文分别进行了讲解。采用的例子为使用Apache作为集群的代理服务器,同时负责负载均衡,然后在两台机器上分别安装两一个Tomcat。如果在一台机器上安装多个Tomcat,需要对端口进行修改,以避免冲突。
Apache接受用户的请求,并根据一定规则将请求转发到两台Tomcat中的一台。Tomcat执行请求后,将结果返回给Apache ,Apache再将结果返回给用户。
2 准备工作
2.1 需要的软件
2.1.1 Apache2.2
本文采用的版本为Apache HTTP Server (httpd) 2.2.19 ,即目前最好用的版本。下载地址http://httpd.apache.org/download.cgi,请分别下载windows和linux版本。
使用Apache2.0或者更低版本时,需要单独安装mod_jk,且配置起来比较繁琐。本文采用的Apache2.2版本已经内置了安装集群所必须的模块,配置更简单。
2.1.2 Tomcat6
本文使用的Tomcat版本,Windows是apache-tomcat-6.0.18,linux是apache-tomcat-6.0.32。
2.2 准备机器
实际应用中,每个Tomcat实例一般部署在单独的机器上,且这些机器需要在同一网段。
本文中两台机器情况如下:第一台机器操作系统Windows,IP为192.168.106.57,安装一个Tomcat,第二台机器操作系统linux,IP为192.168.106.14,安装一个Tomcat和 Apahce。
为了实现session复制,需要注意以下两点:
1. 各tomcat实例需在同一网段下。
2. 所有的session attributes必须实例java.io.Serializable接口。
3 安装软件
3.1 Apache安装
3.1.1 Windows下安装
把Apache安装为运行在80端口的Windows服务,安装成功后在系统服务列表中可以看到Apache2.2服务。服务启动后在浏览器中输入http://localhost进行测试,如果能看到"It works!"的页面就代表Apache已经正常工作了。
3.1.2 Linux下安装
1. 解压文件:
文件 httpd-2.2.18.tar.gz放置在/home/tools/下,我们首先解压它。
[root@localhost ~]#cd /home/tools/ [root@localhost tools]#tar xzvf httpd-2.2.19.tar.gz
2. 配置安装文件:
安装文件我们想把 apache安装到/opt/apache2目录下,让apache启用DSO ,同时启用“proxy proxy_http proxy_ftp proxy_connect proxy_balancer headers”这六个模块。其中 headers不是集群必须的,但是对今后 apache 的应用有好处。
[root@localhost tools]#cd httpd-2.2.18 [root@localhost httpd-2.2.18]#./configure --prefix=/opt/apache2 --enable-so --enable-mods-shared="proxy proxy_http proxy_ftp proxy_connect proxy_balancer headers"
3. 编译安装:
[root@localhost httpd-2.2.18]#make [root@localhost httpd-2.2.18]#make install
make命令读取配置文件进行编译,编译需要花费不短的时间。make install负责安装。
4. 测试一下:
通过命令启动:
Apache[root@localhost httpd-2.2.18]#cd /opt/apache2/bin [root@localhost bin]#./apachectl -k start
在浏览器中输入http://192.168.106.41,如果能看到"It works!"的页面就代表Apache已经正常工作了。
停止命令:[root@localhost bin]#./apachectl -k stop
3.2 Tomcat安装
3.2.1 Windows安装
解压apache-tomcat-6.0.18.zip即可。
3.2.2 Linux安装
首先,将文件 apache-tomcat-6.0.32.tar.gz 拷贝到/opt下:
[root@localhost opt]#cp /home/tools/apache-tomcat-6.0.32.tar.gz /opt
解压:
[root@localhost opt]#tar xzvf apache-tomcat-6.0.32.tar.gz
4 配置过程
4.1 Apache配置
Apahce的配置包含两个方面:虚拟主机和集群配置。
4.1.1 虚拟主机
1. 在Apache安装目录下找到conf/httpd.conf文件,去掉以下文本的注释,以便让Apache在启动时自动加载代理(proxy)模块
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在linux环境中,此配置在Apache安装过程的第二步已经配置好。
<VirtualHost *:80> ServerAdmin 邮箱地址 ServerName 服务器名称 ServerAlias localhost ProxyPass / balancer://cluster/ stickysession=jsessionid nofailover=On ProxyPassReverse / balancer://cluster/ ErrorLog "logs/clustertest-error.log" CustomLog "logs/clustertest-access.log" common </VirtualHost>其中的的virtualHost*:80为HttpServer监听端口。
ProxyRequests Off <proxy balancer://cluster> BalancerMember ajp://192.168.24.87:8009 loadfactor=1 route=jvm1 BalancerMember ajp://192.168.106.14:8009 loadfactor=1 route=jvm2 </proxy>ProxyRequests: Off告诉Apache关闭正向代理,使用反向代理,用于配置工作在tomcat集群中的所有节点。
<Engine name="Catalina" defaultHost="localhost">将其注释掉,并使用默认被注释的
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">这里jvmRoute="jvm1"对应前面Apache集群配置里的route=jvm1,这是192.168.106.57的Tomcat配置,192.168.106.14中的配置为:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm2">2. 配置AJP Connector,这里是Apache和Tomcat链接的关键,前台的apache就是通过AJP协议与Tomcat进行通信的,以完成负载均衡作用。
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />port="8009"和在前面Apache里面配置的AJP端口一样。
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" />这里的配置可以在集群中的所有Tomcat节点间通过复制session共享会话(Session)。但是经过测试session复制不稳定,压力较大的情况下出现了session丢失的情况。其实以上是tomcat6的简化配置,它相当于以下配置的简写:
<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="4000" 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> <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"/>2) Listener
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>以上两个配置是在使用mod_jk 并且没有用sticky sessions或者sticky sessions无法正常工作时的解决方案,我们没有用mod_jk,也就出了现压力较大时session复制失败的情况。因此,我们需要将上面的详细配置替换tomcat6中简化配置,并将上述两条配置去掉。
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <distributable/> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>新建index.jsp:
<?xml version="1.0" encoding="gbk"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title>cluster测试</title> </head> <body> <% out.println("this is tomcat1");//在另一台机子上为”this is tomcat2” String sessionid = session.getId(); out.println("sessionid = " + sessionid); %> </body> </html>
在浏览器地址栏中输入http://localhost/cluster-demo,查看“tomcat1”和“tomcat2”是否按照1:1的比例切换,即是否实现了负载均衡,两个tomcat的sessionid是否一致。
7 参考资料
在写本文的时候,在参考了一下两个地方:
Tomcat关于集群文档http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html
Apache2.2中文文档http://ajava.org/online/apacheMenu2.2/index.html
同时,我上网查询了大量的文章博客,非常感谢你们提供的资料。