Linux+Apache+Tomcat集群配置
参考:
http://blog.csdn.net/bluishglc/article/details/6867358#
http://andashu.blog.51cto.com/8673810/1381369
所搭配环境为centos6.4
本文是采用的mod_jk的方式搭建的集群环境。
一、安装apache
首先安装apache,编译完成后,通过IP:端口访问就行,如果返回“it workers”证明Apache启动成功(注意apache的工程路径要正确)
1.进入下载好的httpd-2.2.25.tar.gz文件所在目录,执行解压操作: tar -zxvf httpd-2.2.25.tar.gz 2.进入解压出的文件夹根目录: cd httpd-2.2.25 3.进行编译参数配置: ./configure --prefix=/usr/local/apache2 --enable-mods-shared=all 关于configure参数的更多内容可参考: http://httpd.apache.org/docs/2.2/en/programs/configure.html#installationdirectories 4.编译安装: make make install 5.启动和关闭apache 完成上述步骤后,apache的安装就结束了,通过下面的命令启动和关闭apache: 启动: /usr/local/apache2/bin/apachectl start 关闭: /usr/local/apache2/bin/apachectl stop apache安装有问题,可以参考 : http://user.qzone.qq.com/1987870278/infocenter#!app=2&via=QZ.HashRefresh&pos=1375688798
关于在安装apache过程中报Cannot use an external APR with the bundled APR-util错误的解决办法 有时候,在安装apache,执行./configure操作时会报这个错误,解决方法是安装apache2.2.x自身携带的apr,方法为: 1.自源码安装目录httpd-2.2.25进入apache2.2.x自带apr的安装目录 cd srclib/apr 2.安装apr(此处将之安装在/usr/local/apr下,如果系统中已经安装apr,可找到安装目录进行覆盖) ./configure --prefix=/usr/local/apr make make install 3.安装apr-util ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr make make install 4.使用新安装的apr重新进行apache编译配置 放回安装根目录httpd-2.2.25,执行: ./configure --prefix=/usr/local/apache2 \ --enable-mods-shared=all \ --with-apr=/usr/local/apr \ --with-apr-util=/usr/local/apr-util/bin 补充:[因为安装的是低版本,这个没有试] 如果你安装是apache-2.4以上版本,有以下几点不同: 1、需要单独下载apr和apr-util apr下载地址: http://mirror.bjtu.edu.cn/apache//apr/apr-1.4.6.tar.bz2 apr-util下载地址:http://mirror.bjtu.edu.cn/apache//apr/apr-util-1.4.1.tar.bz2 2. 此外还需要安装pcre 去http://pcre.org/下载pcre,解压进入源码目录执行 ./configure --prefix=/usr/local/pcre 3. 最后安装apache时configure需要这样配置 ./configure --prefix=/usr/local/apache2 \ --enable-mods-shared=all \ --with-apr=/usr/local/apr \ --with-apr-util=/usr/local/apr-util/bin --with-pcre=/usr/local/pcre
二、安装mod_jk
1.进入下载好的tomcat-connectors-1.2.32-src.tar.gz文件所在目录,执行解压操作:
tar -zxvf tomcat-connectors-1.2.32-src.tar.gz
2.进入解压出的文件夹下的native子目录:
cd tomcat-connectors-1.2.32-src/native
3.进行编译参数配置:
./buildconf.sh
./configure --with-apxs=/usr/local/apache2/bin/apxs --with-java-home=$JAVA_HOME --with-java-platform=2 --enable-jni
执行这步时,可能会提示未安装各种包如autoconf,按提示安装完后再执行就可以。
4.编译安装:
make
make install
如果成功结束,你可以在/usr/local/apache2/modules/下找到mod_jk.so文件。
或直接下载JK,下载地址为http://mirror.bjtu.edu.cn/apache/tomcat/tomcat-connectors/jk/binaries/win32/jk-1.2.31/,如果http服务器是Apache2.0.X版本,则必须选择mod_jk-1.2.31-httpd-2.0.52.so或以上版本,这里宣传的mod_jk-1.2.23-apache-2.2.x-linux-x86_64.so,跟自己操作系统版本吻合,然后重命名为mod_jk.so,并且赋值777权限。
三、安装tomcat
1、下载tomcat,可以通过下面的命令下载:
#wget http://apache.mirror.phpchina.com/tomcat/tomcat-6/v6.0.18/bin/apache-tomcat-6.0.18.tar.gz
2、解压启动测试:
#tar -zxvf apache-tomcat-6.0.18.tar.gz
#./apache-tomcat-6.0.18/bin/startup.sh
在浏览器中输入:http://localhost:8080,看是否启动正常,若正常进行第三步。
3、下面通过一个简单的" Test.jsp "程序进一步验证 Tomcat 是否安装成功。在webapp目录下新建一个项目名称如test,在此目录下新建一个源文件。
新建名称为" Test.jsp "的 Jsp 源文件并在其中输入如下代码。
<%@ page contentType="text/html;charset=GBK"%> <html> <head> <title> Tomcat_ _测试 </title> </head> <body> <font color = "red" size = "20" > <% out.print( "_ _恭喜您,成功的安装并启动了 Tomcat " ); %> </font> </body> </html>
4、重启(命令如下),然后输入:http://localhost:8080/test/Test.jsp 看是否正常。
#./apache-tomcat-6.0.18/bin/shutdown.sh
#./apache-tomcat-6.0.18/bin/startup.sh
安装tomcat成功后。
需要进一步修改/conf/server.xml文件。
四、安装tomcat集群配置。
集群里有多个tomcat时,可先搭建一个tomcat,与apache关联配置没有问题了再安装多个tomcat。当然也可以直接安装多个tomcat直接进行配置。
1、安装两个或以上tomcat
#./apache-tomcat-6.0.18/bin/shutdown.sh
#mv apache-tomcat-6.0.18 /usr/local/TC6_A
#cd /usr/local
#cp -a TC6_A TC6_B
提示:进行上述步骤操作的原因是,本案例中集群的各个 Tomcat 服务器实例运行在同一个物理服务器上,因此集群中有几个 Tomcat 实例一般就需要几个 Tomcat 的安装。另外,由于集群中的各个 Tomcat 实例位于同一个物理服务器上的一个操作系统下,因此各个实例占用的各种网络端口不能相同,否则集群中的多个 Tomcat 实例不能同时正常启动,下面的步骤将介绍如何修改 Tomcat 实例需要使用的各个网络端口。
2、修改 Tomcat 实例需要使用的各个网络端口
对于tomcat配置主要集中在conf/server.xml文件上。首先,鉴于是在同一机器上运行多个tomcat实例,因此,要对 server.xml中配置的所有端口进行修改,避免端口被占用,一种简单而稳妥的修改方法是将该文件中出现的所有端口号按一种简单的规则统一进行改动, 比如在原端口号基础上统一加1000或减1000。基于这个原则,tomcat1的连接端口修改 为:6080,tomcat-2的连接端口修改为:7080,其他端口配置同样依照该原则。
1)找到 server.xml 配置文件中的" Server "配置项目,并进行修改。
<Server port="8005" shutdown="SHUTDOWN"> <Server port="6005" shutdown="SHUTDOWN">
说明:第一行为两个 Tomcat 修改前的情况,第二行为 TC6_A Tomcat 修改后的情况。如果多个tomcat里server的port端口值相同,则只能启动一个tomcat成功。
2)找到 server.xml 配置文件中的相应" Connector "配置项目,并进行修改。
- 修改前内容如下:
<!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port = "8009" protocol = "AJP/1.3" redirectPort = "8443" />
- TC6_A 中修改后内容如下:
<!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port = "6009 " protocol = "AJP/1.3" redirectPort = " 10043 " />
提示:此步骤目的是修改 AJP Connector 端口。
注意:
port 的取值必须要于mod_jk中的workers.properties文件中设置的每个结点名称的port要相对应。
3)找到 server.xml 配置文件中的另一个相应" Connector "配置项目,并进行修改。
- 修改前内容如下:
<Connector port = "8080" protocol = "HTTP/1.1" connectionTimeout = "20000" redirectPort = "8443" />
- TC6_A 中修改后内容如下:
<Connector port = "6080" protocol = "HTTP/1.1" connectionTimeout = "20000" redirectPort = "10043" />
提示:此步骤目的是修改 HTTP Connector 端口,其中的port 是未来通过浏览器访问集群中各个 Tomcat 实例的 HTTP 端口。
4)通过修改 Engine 配置选项,配置集群中每个 Tomcat 实例的名称。
- 修改前内容如下:
<!-- You should set jvmRoute to support load-balancing via AJP ie : <Engine name = "Standalone" defaultHost = "localhost" jvmRoute = "jvm1"> <Engine name = "Catalina" defaultHost = "localhost"> -->
- TC6_A 中修改后内容如下:
<Engine name = "Standalone" defaultHost = "localhost" jvmRoute = "Tomcat1">
提示:注意在修改过程中要注释掉原来 name 为 Catalina 的 Engine 配置项目,将 name 为 Standalone 的 Engine 配置项目的注释去掉并修改 jvmRoute 属性。
注意:
jvmRoute 的取值必须要于mod_jk中的workers.properties文件中设置的结点名称相一致。
因为:该值将做为后缀加在每一个由该结点生成的jsessionid后面,而mod_jk正是根据sessionid后面的这个后缀来确定一个请求应由哪一个结点来处理。(这是实现session_sticky的基本保证)
5)修改配置文件中的 Cluster 配置项目,对集群的各项参数进行设置。——此项是为了做session共享。
- 修改前内容如下:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" />
- TC6_A 中修改后内容如下:
<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>
这份默认配置可以满足大多数应用场景,因此,我们只需要将这份配置复制到<Engine/>中,tomcat的配置就全部完成了。
注意:集群里,每个tomcat里port值要不相同。如tomcat1为4000,tomcat2要为4001
提示:上述配置内容主要是对集群中各个 Tomcat 实例间进行通信的方式、端口以及 Session 共享算法的设置。
3、多个tomcat里,直接将已设置好的server.xml文件拷贝到新的tomcat中将默认的配置文件替换,再按照上述步骤2,修改各个值。
共需要修改5个位置。
五、设置apache集群。
1、打开apache安装目录下的conf/httpd.conf文件,在文件最后追加以下内容:
# Load mod_jk module LoadModule jk_module modules/mod_jk.so # Specify jk log file. JkLogFile /var/log/mod_jk.log # Specify jk log level [debug/error/info] JkLogLevel info # Specify workers.properties, this file tell jk: # how many nodes and where they are. JkWorkersFile conf/workers.properties # Specify which requests should handled by which node. JkMount /* controller
关于mod_jk配置项的详细内容,可参考:http://tomcat.apache.org/connectors-doc/webserver_howto/apache.html
2、根据步骤1的设置,JkWorkersFile conf/workers.properties 指明由一个workers.properties文件来描述集群结点的情况。
因此,我们需要创建这个workers.properties文件,并放置于conf文件夹下,这个文件的内容如下:
#所有节点列表,其中controller是一个逻辑结点,负责负载均衡控制, #如果JkMount中的URL指定给了controller就表示这个请求会被自动散列到某个物理节点上。 #注意:真正负责处理请求的tomcat的名称(这里就是tomcat1,tomcat2)必须于它们在conf/server.xml #文件中配置的jvmRout的属性值是一致的! worker.list = controller,tomcat1,tomcat2 #========tomcat1======== worker.tomcat1.port=6009 #ajp13 端口号,在tomcat下server.xml配置,默认8009 worker.tomcat1.host=localhost #tomcat的主机地址,如不为本机,请填写ip地址 worker.tomcat1.type=ajp13 worker.tomcat1.lbfactor = 1 #server的加权比重,值越高,分得的请求越多 #========tomcat2======== worker.tomcat2.port=7009 #ajp13 端口号,在tomcat下server.xml配置,默认8009 worker.tomcat2.host=localhost #tomcat的主机地址,如不为本机,请填写ip地址 worker.tomcat2.type=ajp13 worker.tomcat2.lbfactor = 1 #server的加权比重,值越高,分得的请求越多 #========controller,负载均衡控制器======== worker.controller.type=lb worker.controller.balance_workers=tomcat1,tomcat2 #指定分担请求的tomcat,旧版本中的balanced_workers,已不再推荐使用! worker.controller.sticky_session=1 #sticky_session为1表示,当某一 client的session创建之后,后续由该客户端发起的请求,也就是这个session的所有请求都始终由第一次处理该请求的结点 #负责处理(除非该结点挂掉)
这里的配置文件为2个tomcat里的配置文件,如果是多个则可以类似修改。
若上述配置文件,启动时只有一个tomcat,则搭建的是相当于是apache与一个tomcat的集群。
3、应用程序要为集群所做的准备
1. 在应用程序的web.xml中需要加入:<distributable/>元素
2. session中存放的数据(如attribute)必须实现序列化。
六、集群方式验证。
到第五步结束后,所有配置均已完成,启动两个tomcat和apache后,将某一应用同时部署到两个tomcat中,通过apache访问这个应用,观察tomcat后台打出的日志会发现,请求被随机分配给了两个tomcat交替执行。
1、页面方式验证
重启apache+加一个tomcat。
测试:
1)http://ip:6080/test/test.jsp,查看是否显示正常,若正常说明tomcat1启动是正常的。
2)http://ip/test/test.jsp ,查看是否显示正常,若正常说明apache+tomcat1集群没有问题。
重启apache+加二台tomcat。
测试:
1)http://ip:6080/test/test.jsp,查看是否显示正常,若正常说明tomcat1启动是正常的。
2)http://ip:7080/test/test.jsp,查看是否显示正常,若正常说明tomcat2启动是正常的。
3)http://ip/test/test.jsp ,查看是否显示正常,若正常说明apache+2台tomcat集群设置成功。
为验证集群策略,可以将test.jsp页面将当前的tomcat实例名称打印出来。
客户端打开此页面时,查看页面是否会显示不同的tomcat实例名称。
2、可以直接查看apache与tomcat的日志,可看出集群是否生效。
关于apache+tomcat的session共享
http://andashu.blog.51cto.com/8673810/1381370
实现了负载均衡,现在我们实现session共享 一、tomcat集群配置,session 同步配置: tomcat1配置 A、修改Engine节点信息: <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"> B、去掉<Cluster> <\Cluster> 的注释符 C、修改Cluster 节点信息 <Membership className="org.apache.catalina.cluster.mcast.McastService" mcastBindAddress="127.0.0.1" #IP自己配置,远程的话写远程IP mcastAddr="224.0.0.1" mcastPort="45564" mcastFrequency="500" mcastDropTime="3000"/> <Receiver className="org.apache.catalina.cluster.tcp.ReplicationListener" tcpListenAddress="127.0.0.1" tcpListenPort="4001" tcpSelectorTimeout="100" tcpThreadCount="6"/> tomcat2配置: A、修改Engine节点信息: <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2"> B、去掉<Cluster> <\Cluster> 的注释符 C、修改Cluster 节点信息 <Membership className="org.apache.catalina.cluster.mcast.McastService" mcastBindAddress="127.0.0.1" #IP自己配置 mcastAddr="224.0.0.1" mcastPort="45564" mcastFrequency="500" mcastDropTime="3000"/> <Receiver className="org.apache.catalina.cluster.tcp.ReplicationListener" tcpListenAddress="127.0.0.1" #IP自己配置 tcpListenPort="4002" # 一定要改 tcpSelectorTimeout="100" tcpThreadCount="6"/> 修改web应用里面WEB-INF目录下的web.xml文件,加入标签 <distributable/> 直接加在</web-app>之前就可以了 做tomcat集群必须需要这一步,否则用户的session就无法正常使用。 注意事项: 1、mcastAddr="224.0.0.1"这主广播地址因此需要开启网卡组播功能 route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0 分别在各机器上运行 2、查看端口情况:Netstat –antl |grep 4001 同步监听的端口(2台tomcat在不同机器情况下) tocat1 200811181227002475084.jpg tomcat2 200811181227002481388.jpg 3、测试广播: java -cp tomcat-replication.jar MCaster 224.0.0.1 45564 Terminal1 java -cp tomcat-replication.jar MCaster 224.0.0.1 45564 Terminal2 如果不报错则能正常广播tomcat-replication.jar 下载:[url]http://cvs.apache.org/~fhanik/tomcat-replication.jar[/url]如果是二台机器,可以用tcpdump 抓取包 二、测试集群及session同步 在2个tomct的webapps 下新建test 目录目录下建WEB-INF目录下的web.xml文件 <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee [url]http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd[/url]" version="2.4"> <display-name>TomcatDemo</display-name> <distributable/> </web-app> 再在webapps 下建立print.jsptest.jsp Print.jsp : <% System.out.println("http://andashu.blog.51cto.com/); %> test.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>"); String dataName = request.getParameter("dataName"); session.setAttribute("myname","session?"); if (dataName != null && dataName.length() > 0) { String dataValue = request.getParameter("dataValue"); session.setAttribute(dataName, dataValue); } out.print("<b>Session P±?b>"); 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" method="POST"> 3?<input type=text size=20 name="dataName"> <br> ?:<input type=text size=20 name="dataValue"> <br> <input type=submit> </form> </body> </html> 重启所有的服务。 访问[url]http://192.168.19.199/test/print.jsp[/url] 如图可以看出tomcat 集群配置完成 spacer.gifwKioL1MsmXLDq3i0AAFlFkwY8IQ185.jpg Session 复制的查看: 在同一窗口,输入名称和值, 在2个tomcat日志里能看到同样内容的日志,就表明成功了。