2013-11-14 12:03:01
来 源
ITJS.CN
Apache
本文介绍Windows系统中配置Apache2.2与Tomcat7集群服务器环境,希望对于初学Apache服务器相关的朋友有帮助,更多Apache安装、配置、报错处理等资源请本站内搜索。

今天终于搞定了Apache和tomcat7整合集群以及负载均衡的问题,在此做个记录。

客户的网站有时候会因为一个tomcat6的错误down掉,又比较难查出示什么原因,而且是没什么规律的。所以狠下心来做了个tomcat6到7的升级,并使用了tomcat7的集群。

要说Tomcat7和6的配置确实有些不同,以前我在Server.xml的Engine节点内增加一个Listener就能自动生成一个mod_jk.conf-auto配置文件,包含到apache/conf/httpd.conf里面,然后修改一下就行了。现在就不同了,以下是我Tomcat6的server.xml配置。

<Listener className="org.apache.jk.config.ApacheConfig" modJk="D:/Apache2.213/modules/mod_jk-1.2.26-httpd-2.2.4.so" />

虽然提示我什么workers.properties找不到,但是照样能用。

Tomcat7里面这招不好用了,写上这句就会报错误。无语了。只能狠下心重新查资料,看了网上的一些文章和tomcat自己带的文档。终于搞出来了,下面就跟大家分享一下我的经验,本人水平确实有限,望大家拍砖。

首先说一下我的服务器端软件

1.Apache,我采用带SSL模块的,因为我以后还要做CAS配置用,如果不用SSL版本也一样。httpd-2.2.17-win32-x86-openssl-0.9.8o.msi

2.Tomcat版本是7.0.12,解压版的,要做集群,自动安装服务的有点不爽。

一、配置apache

1.加载链接器so文件

安装就不说了,装好后,打开apache_home/conf/httpd.conf,找到如下文本:

#LoadModule jk_module modules/mod_jk.so

把它的注释去掉,从apache官网上找对应的Connector,我这个版本apache对应的是mod_jk-1.2.28-httpd-2.2.3.so。对于这块不熟的朋友我简单说一下:其中 1.2.28是Connector的版本,后面的2.2.3是对应的apache版本。其中主要是apache的版本要对应,没有正好匹配的要找相近的。我把 LoadModule jk_module modules/mod_jk.so改为: LoadModule jk_module modules/mod_jk-1.2.28-httpd-2.2.3.so。当然你也可以把so文件修改文件名为 mod_jk.so。当然这个so文件要放在 apache_home/modules里了,否则得写绝对路径了。

这一步就算做好了,重启apache,如果没有错误说明OK。有错误无非2个。一个是文件路径写错了;另一个是so的版本与apache不匹配。

2.增加apche与tomcat的连接

在httpd.conf文件的末尾增加一句:Include conf/mod_jk.conf

包含mod_jk的配置文件,当然这个文件我们还得自己建立。

以下是我的mod_jk.conf内容:

JkWorkersFile conf/workers.properties

JkLogFile logs/mod_jk.log

JkLogLevel info

JkRequestLogFormat "%w %V %T"

JkMount /* controller

Alias /cas "D:/apache-tomcat-7.0.12/webapps/cas"

<Directory "D:/apache-tomcat-7.0.12/webapps/cas">

#Options FollowSymLinks

#AllowOverride None

</Directory>

Alias /cas "D:/apache-tomcat-7.0.12/webapps/cas"和它下面的配置是我做cas的,不必理会,可以不要。

JkWorkersFile conf/workers.properties指明worker的配置文件名,这也需要自己写。

JkMount /* controller 中的“controller”是在workers.properties中配置的,目前先这么写吧。

其他几行都是日志的配置,当时大家最好都加上,因为配置中随时有可能失败,在日志里可以查看到底出了什么错误。

JkMount /* controller这句的还以大家应该都明白,相当于以前自动生成配置中的 JkMount /* ajp13

当然这样配置只是为了方便,把所有的请求都转发到tomcat了,实际上肯定不会这么做的,否则apache只有纯转发的功能了,我们只需要把需要执行java代码的地址转发给tomcat,实际上可能这样配置:

JkMount /*.do controller

JkMount /*.jsp controller

JkMount /yourServletURL controller

我自己是配置一个VirtualHost,在VirtualHost配置这些转发的。

以下是我的workers.properties内容

worker.list=controller

worker.controller.type=lb

worker.controller.sticky_session=1

worker.controller.error_escalation_time=0

worker.controller.max_reply_timeouts=10

# localhost server 1

# ------------------------

worker.jvm1.reference=worker.template

worker.jvm1.port=8009

worker.jvm1.host=localhost

worker.jvm1.lbfactor = 5

worker.jvm1.activation=A

# localhost server 2

worker.jvm2.reference=worker.template

worker.jvm2.port=8019

worker.jvm2.host=localhost

worker.jvm2.lbfactor=1

worker.jvm2.activation=A

worker.template.type=ajp13                   

worker.template.socket_connect_timeout=5000

worker.template.socket_keepalive=true

worker.template.ping_mode=A

worker.template.ping_timeout=10000

worker.template.connection_pool_minsize=0

worker.template.connection_pool_timeout=600

worker.template.reply_timeout=300000

worker.template.recovery_options=3

worker.controller.balance_workers=jvm1,jvm2

具体的那些参数就不细说了,重点是tomcat的端口,默认的tomcat ajp13的端口是8009。我是在一台机器上配的2个tomcat,所以ajp的端口分别是8009和8019,还有worker.jvm1和 worker.jvm2分别代表2个Tomcat.这个在tomcat的server.xml中也有体现,下面再说这个。

还有就是worker.controller.sticky_session=1这个参数配置为true或者1,说明需要session复制。

二、配置Tomcat7

打开Tomcat7的server.xml,找到<Server port="8005" shutdown="SHUTDOWN">,其中一个tomcat要把这个端口改掉,还有默认的8009,8080,8443端口,只要一台机器上部署多个Tomcat,这些端口不能重复的,反正访问的时候也不会用这些端口访问,随便改了。要注意的是<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="GBK"/>,这个东西,port的值要和 workers.properties 中的 worker.jvm1.port、 worker.jvm2.port匹配。

找到<Engine name="Catalina" defaultHost="localhost">,修改为<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">(第一个tomcat)和<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm2">(第二个Tomcat),这里的 jvmRoute的值就是workers.properties里的值了,匹配就好。

在Engine节点内,增加如下配置:

<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="4001" 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>

那个注释掉Deployer不能加,会报个严重错误(虽然能启动成功),而且这东西是集群同步文件的,而且没有实现。上面这一段配置不用修改,端口、地址之类的不用动,原样复制就可以。

这样Tomcat就算配置好了。测试一下,需要在应用的 web.xml中 web-app节点内增加

<distributable/> 配置,这样程序就会知道需要集群了。在2个tomcat上搞2个一样的应用试验一下吧,停止一个tomcat,访问还是会成功的。

需要注意的地方:

1.配置好mod_jk的日志文件,有问题随时看。

2. 如果你用的不是 mod_jk-1.2.28-httpd-2.2.3.so,比如我之前用的 mod_jk-1.2.26-httpd-2.2.4.so,可以用,但是 workers.properties里某些属性不支持,这我也是在日志里看到的,但是去掉不支持的属性也能用。

3. 如果程序需要文件上传,不要上传到web目录下,最好配置上传到单独的目录中,这样集群中的所有应用才好共享同一个上传目录。否则如果一个tomcat不运行了,另一个tomcat在运行时查找本应用下的上传文件可能会找不到,因为可能传到死掉的那个tomcat应用目录下了。如果需要用浏览器直接访问这些上传的文件(不需权限控制),应该在Apache里给上传文件的路径配置一个Directory。确保文件通过web能够正常访问。我的配置如下:

<VirtualHost *:80>

ServerAdmin [email protected]

ServerName www.xxx.cn

ServerAlias xxx.cn

#Allow from xxx.cn

ErrorLog logs/xxx.cn-error_log

CustomLog logs/xxx.cn-access_log common

DocumentRoot "E:/wwwroot/xxx_a" #主tomcat(第一个)应用根目录,我的程序叫xxx,部署2个分别较xxx_a,xxx_b

DirectoryIndex index.do index.jsp

Alias /html "E:/html" #生成静态文件的目录

<Directory E:/html>

Options FollowSymLinks

AllowOverride None

</Directory>

Alias /imageupload "D:/imageupload" #图片上传的目录

<Directory D:/imageupload>

Options FollowSymLinks

AllowOverride None

</Directory>

Alias /userfiles "E:/wwwroot/userfiles" #FckEditor的上传目录

<Directory E:/wwwroot/userfiles>

Options FollowSymLinks

AllowOverride None

</Directory>

#禁止访问的路径配置,不让用户通过浏览器访问WEB-INF

<Directory E:/wwwroot/xxx_a/WEB-INF/>

Options FollowSymLinks

AllowOverride None

Order deny,allow

Deny from all

</Directory>

</VirtualHost>

4.如果web应用里有一些后台线程或后台任务之类的东西,最好的方式是单独做成一个非web应用,独立运行,这也是servlet规范推荐的方式。不方便的话,需要在web应用中配置一个参数,指定集群中的某一个实例运行这些线程,不要一个web程序的所有部署 实例 都运行线程,那样可能出现意想不到的后果。

声明: 此文观点不代表本站立场;转载须要保留原文链接;版权疑问请联系我们。