Windows中Apache2.2 Tomcat7 集群配置

来源:互联网 发布:windows抄袭mac字体 编辑:程序博客网 时间:2024/04/30 08:33

今天终于搞定了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 aaa@yeah.net
    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程序的所有部署实例都运行线程,那样可能出现意想不到的后果。

原创粉丝点击