apache、mod_jk负载均衡与tomcat集群

时间:2022-04-29 22:42:40

         最近需要搭建apache和tomcat的集群,实现静态网站直接通过apache访问,动态网站转交给tomcat处理,实现负载均衡和tomcat集群配置。

  • apache安装
              wget http://apache.fayea.com/apache-mirror//httpd/httpd-2.4.9.tar.bz2
tar -xvf httpd-2.4.9.tar.bz2
cd httpd-2.4.9
./configure
make && make install
make clean
make distclean
             在./configure时,若未安装apr、apr-util、pcre,则需要安装。
  • apache配置
             1) vi /usr/local/apache/conf/httpd.conf             1、添加监听
         Listen 192.168.1.100:80
             2、设置服务器主机名                   ServerName 192.168.1.100:80                     有绑定域名主机名设定域名+端口号,若没有域名则使用ip地址+端口号              3、设定默认的根目录               
         DocumentRoot "/home/apache2/htdocs"
             4、进行访问授权                  
          Require all granted
             5、启用虚拟目录
         Include conf/extra/httpd-vhosts.conf
             b) 设置虚拟目录
        <VirtualHost 192.168.1.100:80>
            DocumentRoot "/home/apache2/htdocs/resource"
            ServerName   www.xx.com
            ErrorLog "logs/www.xx.com.error_log"
            CustomLog "logs/www.xx.com.access_log" common
        </VirtualHost>
  •  apache注册为系统服务
       apache 配置为服务启动
cp /usr/local/httpd/bin/apachectl /etc/rc.d/init.d/httpd
vi httpd
找到:#!/bin/sh
另起一行,增加:
# chkconfig: 35 70 30
# description: Apache
然后注册服务:chkconfig --add httpd
启动服务:service httpd start
停止服务:service httpd stop
重新启动:service httpd restart
  • tomcat安装与配置
              参考以前写过文章

  • tomcat集群实现环境

             访问节点A:JVMRoute-pj001 IP:192.168.1.101
             访问节点B:JVMRoute-pj002 IP:192.168.1.102

  • 实现目标
        1.  整合apache+tomcat ,由apache提供统一接受所有访问。
        2.  站点A、站点B实现apache负载均衡和tomcat集群。
        3.  站点C指定由JVMRoute-pj001节点进行访问。
        4.  静态网站和动态网站中的静态文件,统一由apache提供访问,不经过tomcat进行访问。

  • 实现意义
        1.  实现分布式访问
           支持将各个服务分布在不同的服务器上
        2.  支持动态扩容
           根据业务发展需要可以随时方便添加访问节点,而不影响已有的服务提供访问
        3.  提供系统容错功能。
           当其中的一个节点不能提供访问服务时,用户的访问服务会自动被转交到其他的服务器节点处理。
        4.  提升网站的访问速度
           实现静态文件和静态页面由apache进行处理,提高访问能力,动态页面根据jk_mod根据各个服务器节点权重分配各个tomcat进行处理。
  • 负载均衡实现的两种方式

             1、mod_jk              

             2、mod_proxy

             本文是基于mod_jk进行配置的

  • mod_jk安装配置

      1、下载mod_jk并安装mod_jk
            下载地址:http://tomcat.apache.org/download-connectors.cgi

       wgethttp://mirrors.cnnic.cn/apache/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.40-src.tar.gz
tar -xzvftomcat-connectors-1.2.40-src.tar.gz
cd/tomcat-connectors-1.2.40-src/native/
./configure--with-apxs=/usr/local/apache2/bin/apxs
make&& make install
  make clean

             mod_jk.so会安装在/usr/local/apache2/modules/mod_jk.so

      2、如果在安装apr环境变量,则需要配置apr环境变量

        在安装完毕后会提示以下内容

        Libraries have been installed in:
           /usr/local/apache2/modules

        If you ever happen to want to link against installed libraries
        in a given directory, LIBDIR, you must either use libtool, and
        specify the full pathname of the library, or use the `-LLIBDIR'
        flag during linking and do at least one of the following:
           - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
             during execution
           - add LIBDIR to the `LD_RUN_PATH' environment variable
             during linking
           - use the `-Wl,-rpath -Wl,LIBDIR' linker flag
           - have your system administrator add LIBDIR to `/etc/ld.so.conf'

        See any operating system documentation about shared libraries for
        more information, such as the ld(1) and ld.so(8) manual pages.
        ----------------------------------------------------------------------
        chmod 755 /usr/local/apache2/modules/mod_jk.so

        Please be sure to arrange /usr/local/apache2/conf/httpd.conf...

              根据提示,设置mod_jk环境变量                 

        export APR_HOME=/usr/local/apr

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$APR_HOME/lib

export LD_RUN_PATH=$LD_RUN_PATH:$APR_HOME/bin

export PATH=$PATH:$LD_RUN_PATH

export CLASSPATH=$CLASSPATH:$LD_LIBRARY_PATH
  • httpd.conf配置

            #加载http_jk.conf并引用http_jk的配置文件

   

       include          conf/extra/http_jk.conf

    # 加载 mod_jk 模块

       LoadModule    jk_module modules/mod_jk.so

  • 配置httpd-vhost.conf文件

        # Virtual Hosts
#
# Required modules: mod_log_config

# If you want to maintain multipledomains/hostnames on your
# machine you can setup VirtualHostcontainers for them. Most configurations
# use only name-based virtual hosts sothe server doesn't need to worry about
# IP addresses. This is indicated by theasterisks in the directives below.
#
# Please see the documentation at
#<URL:http://httpd.apache.org/docs/2.4/vhosts/>
# for further details before you try tosetup virtual hosts.
#
# You may use the command line option'-S' to verify your virtual host
# configuration.

#
# VirtualHost example:
# Almost any Apache directive may go intoa VirtualHost container.
# The first VirtualHost section is usedfor all requests that do not
# match a ServerName or ServerAlias inany <VirtualHost> block.

<VirtualHost IP:80>
ServerAdmin service@域名.com
ServerName 域名
DocumentRoot"/home/webapps/应用程序目录"
DirectoryIndexindex.do login.do index.jsp login.jsp
ErrorLog"/home/logs/apache2/域名.com-error_log"
CustomLog"/home/logs/apache2/域名-access_log" common

JkMount /*.jspjk_controller
JkMount /*.dojk_controller
JkMount /*Servletjk_controller
JkMount /Servlet/*jk_controller
JkMount /servlet/*jk_controller
JkMount /kaptcha.jpg*jk_controller
JkMount/j_spring_security_check jk_controller
JkMount /jkStatusjk_watcher

<Directory"/home/webapps/应用程序目录">
OptionsMultiViews
AllowOverrideNone
Allow from all
</Directory>
</VirtualHost>
  • httpd_jk.conf 配置

            httpd_jk.conf主要定义 mod_jk 模块的位置、哪些访问地址需要转交给tomcat应用服务器处理、及 mod_jk 模块的连接日志设置,还有定义 worker.properties 文件的位置。在/usr/local/apache2/conf/extra/目录下创建httpd_jk.conf配置文件,并写入如下内容:

        # 指定  workers.properties 文件路径

JkWorkersFileconf/workers.properties

# 指定那些请求交给 tomcat 处理 ,"jk_controller" 为在 workers.propertise 里指定的负载分配控制器

JkMount /*.jspjk_controller

JkMount /*.dojk_controller

JkMount /*.action jk_controller

JkMount /*Servletjk_controller

JkMount /Servlet/*jk_controller

JkMount /servlet/*jk_controller

#JkMount/j_spring_security_check jk_controller

# 指定 log 目录

JkLogFile/home/logs/apache2/mod_jk/mod_jk2.log

JkShmFile/home/logs/apache2/mod_jk/mod_jk.shm

# Set the jk loglevel [debug/error/info]

JkLogLevel info

# Select the logformat

JkLogStampFormat"[%a %b %d %H:%M:%S %Y]"
# JkOptions indicateto send SSL KEY SIZE,

JkOptions+ForwardKeySize +ForwardURICompat -ForwardDirectories

#JkRequestLogFormat set the request format

JkRequestLogFormat"%w %V %T"

             需要配置JkShmFile路径,否则会提示以下错误

            

       No JkShmFiledefined in httpd.conf. Using default /usr/local/apache2/logs/jk-runtime-status

            apache不会过滤配置中的命令行的空格,因此我们必须保证命令与参数之间是真正的空格隔开,另外在配置文件尾部不能有多余的空行,否则在启动 apache时,会出现类似以下这样的错误提示,另外也要注意apache无法识别中文字符。否则提示类似下面的错误

       AH00526:Syntax error on line 12 of /usr/local/apache2/conf/extra/http_jk.conf:

Invalidcommand 'JkMount\xc2\xa0/*\xc2\xa0controller\xc2\xa0', perhaps misspelled ordefined by a module not included in the server configuration

AH00526:Syntax error on line 12 of /usr/local/apache2/conf/extra/mod_jk.conf:

JkMountneeds a path when not defined in a location
  • workers.properties配置   

             1、worker常见属性

                    ajp13 :此类型表示当前worker为一个运行着的Tomcat实例。

                    lb :lb即load balancing,专用于负载均衡场景中的woker;此worker并不真正负责处理用户请求,而是将用户请求调度给其它类型为ajp13的worker。

                    status:用户显示分布式环境中各实际worker工作状态的特殊worker,它不处理任何请求,也不关联到任何实际工作的worker实例。具体示例如请参见后文中的配置

                    host :Tomcat7的worker实例所在的主机

                    port :Tomcat7实例上AJP1.3连接器的端口

                    connection_pool_minsize  :最少要保存在连接池中的连接的个数;默认为pool_size/2

                    connection_pool_timeout  :连接池中连接的超时时长

                    mount :由当前worker提供的context路径,如果有多个则使用空格格开;此属性可以由JkMount指令替代

                    retries :错误发生时的重试次数

                    socket_timeout :mod_jk等待worker响应的时长,默认为0,即无限等待

                    socket_keepalive :是否启用keep alive的功能,1表示启用,0表示禁用

                    lbfactor :worker的权重,可以在负载均衡的应用场景中为worker定义此属性     

                    balance_workers :用于负载均衡模式中的各worker的名称列表,需要注意的是,出现在此处的worker名称一定不能在任何worker.list属性列表中定义过,并且worker.list属性中定义的worker名字必须包含负载均衡worker。具体示例请参见后文中的定义。

                    method:可以设定为R、T或B;默认为R,即根据请求的个数进行调度;T表示根据已经发送给worker的实际流量大小进行调度;B表示根据实际负载情况进行调度。

                   sticky_session:在将某请求调度至某worker后,源于此址的所有后续请求都将直接调度至此worker,实现将用户session与某worker绑定。默认为值为1,即启用此功能。如果后端的各worker之间支持session复制,则可以将此属性值设为0。


             2、worker配置

                    mod_jk安装包tomcat-connectors-1.2.32-src中已经自带了workers.properties包含默认配置和最小配置 两种,也可以自行创建workers.properties,然后将workers.properties上传到/usr/local/apache2/conf目录下,以下是workers.properties的配置内容 

        worker.list=jk_controller,jk_watcher,JVMRoute-pj001,JVMRoute-pj002
        #由于是不同服务器,因此监听端口可以都是8009,否则要求保证端口唯一

        #JVMRoute-pj001的tomcat节点配置,JVMRoute-pj001为主站点,第一优先访问
        worker.JVMRoute-pj001.type=ajp13
        worker.JVMRoute-pj001.host=192.168.1.101
        worker.JVMRoute-pj001.port=8009
        worker.JVMRoute-pj001.lbfactor=1
        #apache服务器是多线程的,tomcat能够利用这一优势来维持一定数量的连接作为缓存。
        #worker.JVMRoute-pj001.cachesize=1000
        #worker.JVMRoute-pj001.cache_timeout=600
        # 指定 JVMRoute-pj001 无法提供服务后由 JVMRoute-pj002 继续提供服务
        worker.JVMRoute-pj001.redirect=JVMRoute-pj002
        worker.JVMRoute-pj001.sticky_session=0
        worker.JVMRoute-pj001.sticky_session_force=0

        #JVMRoute-pj002的tomcat节点配置
        #JK模块实现负载均衡采用的是AJP协议1.3版本,负载均衡服务器的类型配置为ajp13
        worker.JVMRoute-pj002.type=ajp13
        #负载均衡服务器的主机名、域名或者IP地址
        worker.JVMRoute-pj002.host=192.168.1.102
        #负载均衡服务器AJP协议连接器的连接端口
        worker.JVMRoute-pj002.port=8009
        #负载均衡服务器在整个负载均衡系统中所占的权重
        worker.JVMRoute-pj001.lbfactor=1
        #apache服务器是多线程的,tomcat能够利用这一优势来维持一定数量的连接作为缓存。
        #worker.JVMRoute-pj002.cachesize=1000
        #worker.JVMRoute-pj002.cache_timeout=600
        # 指定 JVMRoute-pj002 无法提供服务后由 JVMRoute-pj001 继续提供服务
        worker.JVMRoute-pj002.redirect=JVMRoute-pj001
        worker.JVMRoute-pj002.sticky_session=0
        worker.JVMRoute-pj002.sticky_session_force=0

        #========jk_controller,负载均衡控制器========
        #这里配置为lb,也就是Load Balance负载均衡
        worker.jk_controller.type=lb
        #拥有哪些负责负载均衡的服务器实例
        worker.jk_controller.balance_workers=JVMRoute-pj001, JVMRoute-pj002
        #设置负载均衡是否采用粘性会话。如果该属性设置为true,假设一个请求被s1处理了,下次来源于同一个客户端的请求也将被s1处理。
        worker.jk_controller.sticky_session=0
        worker.jk_controller.sticky_session_force=0


        #========jk_watcher,负载均衡监视器========
        worker.jk_watcher.type=status
        worker.jk_watcher.read_only=false
        #设置名称为jk_watcher的负载均衡服务器实例监视器的挂载路径,通过http://192.168.1.101/jkStatus访问
        worker.jk_watcher.mount=/jkStatus
        #worker全局的重试次数。在apache服务器启动后,会最多尝试若干次去连接这些负载均衡服务器,若连接不上就认为是down掉了,这里配置为3

               负载均衡监控平台访问地址:http://ip地址/jkStatus

  • tomcat集群的基础

              1、是否支持组播通讯

                    含有UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1表示支持组播通讯

        eth2      Link encap:Ethernet  HWaddr 28:6E:D4:88:C7:21  
              inet addr:172.20.206.149  Bcast:172.20.206.151  Mask:255.255.255.248
              inet6 addr: fe80::2a6e:d4ff:fe88:c721/64 Scope:Link
              <strong>UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1</strong>
              RX packets:1736039 errors:0 dropped:0 overruns:0 frame:0
              TX packets:730940 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000
              RX bytes:372044172 (354.8 MiB)  TX bytes:133741508 (127.5 MiB)
              Interrupt:28

        lo        Link encap:Local Loopback  
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:65536  Metric:1
              RX packets:36958 errors:0 dropped:0 overruns:0 frame:0
              TX packets:36958 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0
              RX bytes:12524870 (11.9 MiB)  TX bytes:12524870 (11.9 MiB)
              2、设置防火墙,tomcat集群要开放以下端口

                     vi /etc/sysconfig/iptables 要开放的端口,45564,8005,8080,8009,8443, 4000-4100网段的端口等

        -A INPUT -m state --state NEW -m tcp -p tcp --dport 8005 -j ACCEPT
        -A INPUT -m state --state NEW -m tcp -p tcp --dport 8009 -j ACCEPT
        -A INPUT -m state --state NEW -m tcp -p tcp --dport 8443 -j ACCEPT
        -A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT
        -A INPUT -m state --state NEW -m udp -p udp --dport 45564 -j ACCEPT
        -A INPUT -m state --state NEW -m tcp -p tcp --dport 4000:4100 -j ACCEPT
                 其中要特别注意 45564端口是组播通讯端口,以udp协议进行通讯,必须正确设置否则无法集群通讯。4000-4100端口是以tcp进行通讯的。
                若要看iptable的规则配置是否成功,使用iptables -L查看结果             
        ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:45564 

              3、添加路由信息

          route add -net 224.0.0.0 netmask 240.0.0.0 dev eth2
                    查看添加后的路由表

          route -n

  • 修改tomcat配置文件                     

              1、修改链接器端口号

                   若是同一台服务部署多个tomcat,则链接器的端口号必须保证唯一,若是不同台服务器,由于ip不一样可以不修改

         <Connector port="8009" protocol="AJP/1.3"redirectPort="8443" />

             2、定义Engine节点的jvmRoute名称   

         <Engine name="Catalina"defaultHost="localhost"> 

                改为

         <Enginename="Catalina"    defaultHost="localhost"jvmRoute="JVMRoute-pj001">  

                 其中JVMRoute-pj001必须与workers.properties中的定义的保持一致

             3、启用tomcat集群,实现session共享

                  配置集群有两种方式,一种是节点对节点的全拷贝,就是all to all,以下第一种就是,配置起来比较简单。另外一种是根据需要进行配置。tomcat7默认是采用DeltaManager模式,它通过将改变了会话数据同步给集群中的其它节点实现会话复制。

                  1、最简单的tomcat集群配置

         <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

                   2、server.xml集群配置信息

      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
        <Manager
            className="org.apache.catalina.ha.session.BackupManager"
            expireSessionsOnShutdown="false"
            notifyListenersOnReplication="true"
            mapSendOptions="6"
        />

        <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="192.168.1.101"
                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"/>
        <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
        <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
      </Cluster>  

             Tomcat会在创建session时会根据根据jvmRoute的值在sessionID后面追加route值(接下来将要配置),例如167A7621C8ACEF496A0E3D7720F7C35E.jvm1。客户端访问时,如果是已建立的session,有route值,apache就sticky session,使该请求一直分发到上次访问的tomcat server上,如果是第一次请求则根据既定规则分发。

              Manager用来在节点间拷贝Session,默认使用DeltaManager,DeltaManager采用的一种all-to-all的工作方式,即集群中的节点会把Session数据向所有其他节点拷贝,而不管其他节点是否部署了当前应用。当集群中的节点数量很多并且部署着不同应用时,可以使用BackupManager,BackManager仅向部署了当前应用的节点拷贝Session。但是到目前为止BackupManager并未经过大规模测试,可靠性不及DeltaManager。

               Membership用于发现集群中的其他节点,这里的address用的是组播地址使用同一个组播地址和端口的多个节点同属一个子集群,因此通过自定义组播地址和端口就可将一个大的tomcat集群分成多个子集群。

               receiver用于各个节点接收其他节点发送的数据,在默认配置下tomcat会从4000-4100间依次选取一个可用的端口进行接收,自定义配置时,如果多个tomcat节点在一台物理服务器上注意要使用不同的端口。

               Sender用于向其他节点发送数据,具体实现通过Transport配置

               Channel 是一个抽象的端口,和socket类似,集群member通过它收发信息。

               Valve用于在节点向客户端响应前进行检测或进行某些操作,ReplicationValve就是用于检测当前的响应是否涉及Session数据的更新,如果是则启动Session拷贝操作,filter用于过滤请求,如客户端对图片,css,js的请求就不会涉及Session,因此不需检测,默认状态下不进行过滤,监测所有的响应。

               在生产环境中使用以下选项:

               <Valve className=”org.apache.catalina.ha.tcp.ReplicationValve”  filter=”.*\.gif;.*\.js;.*\.jpg;.*\.htm;.*\.html;.*\.txt;”/>

               即当对静态页面图片等访问时不进行session replication。

               <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

              设置此选项是,当一个节点crash时,访问跳到另一个节点,此时session ID 会将jvmRoute值和以前的session Id 绑定在一起向新的节点发送



  • 域名绑定访问

               1、apache:修改/usr/local/apache2/conf/extra/httpd-vhosts.conf,假设站点目录为/home/webapps/site

               <VirtualHostip地址:80>
ServerName 域名
ServerAlias 域名
DocumentRoot "/home/webapps/site"
ErrorLog "/home/logs/apache2/域名-error_log"
CustomLog "/home/logs/apache2/域名-access_log" common
JkMount /*.jspjk_controller
JkMount /*.do jk_controller #负载均衡器自动分配哪个服务器解析
JkMount /*Servlet JVMRoute-pj001 #指定哪个服务器解析
JkMount /Servlet/* JVMRoute-pj001
JkMount /servlet/* JVMRoute-pj001
JkMount /j_spring_security_check JVMRoute-pj001
JkMount /jkStatus jk_watcher
<Directory"/home/webapps/site">
Options MultiViews
AllowOverride None
Allow from all
</Directory>
</VirtualHost>

              2、修改/usr/local/tomcat/conf/server.xml

            <Host name="www.站点域名.com" debug="0"appBase="webapps"
unpackWARs="true"autoDeploy="true">
<alias>www.站点域名.com</alias>
<Contextpath="" docBase="/home/webapps/site" debug="0"reloadable="true"/>
</Host>

  • 出现的问题

        
        Apr 13, 2015 11:36:24 AM org.apache.catalina.core.StandardService startInternal
        INFO: Starting service Catalina
        Apr 13, 2015 11:36:24 AM org.apache.catalina.core.StandardEngine startInternal
        INFO: Starting Servlet Engine: Apache Tomcat/7.0.57
        Apr 13, 2015 11:36:24 AM org.apache.catalina.ha.tcp.SimpleTcpCluster startInternal
        INFO: Cluster is about to start
        Apr 13, 2015 11:36:24 AM org.apache.catalina.tribes.transport.ReceiverBase bind
        INFO: Receiver Server Socket bound to:/172.20.206.149:4000
        Apr 13, 2015 11:36:24 AM org.apache.catalina.tribes.membership.McastServiceImpl setupSocket
        INFO: Setting cluster mcast soTimeout to 500
        Apr 13, 2015 11:36:24 AM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
        INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:4
        Apr 13, 2015 11:36:25 AM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
        INFO: Done sleeping, membership established, start level:4
        Apr 13, 2015 11:36:25 AM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
        INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:8
        Apr 13, 2015 11:36:26 AM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
        INFO: Done sleeping, membership established, start level:8
        Apr 13, 2015 11:36:28 AM org.apache.catalina.core.ApplicationContext log
        INFO: Log4jServletContainerInitializer starting up Log4j in Servlet 3.0+ environment.
                出现上面的情况,其实tomcat集群虽然配置成功,但是并未通讯成功,这主要是防火墙配置存在问题,由于tcp集群采用组播通讯,而组播是使用udp协议进行通讯,刚开始的防火墙端口开放中,一直使用tcp进行通讯,因此tomcat集群的访问的时候,sessionid的前缀一直变化,网上所说的情况都无法解决。防火墙的端口开放规则为
当出现以下内容特别是红色的部分的时候才表示真正通讯成功

        Apr 13, 2015 2:05:22 PM org.apache.catalina.ha.tcp.SimpleTcpCluster startInternal
        INFO: Cluster is about to start
        Apr 13, 2015 2:05:22 PM org.apache.catalina.tribes.transport.ReceiverBase bind
        INFO: Receiver Server Socket bound to:/172.20.206.149:4000
        Apr 13, 2015 2:05:22 PM org.apache.catalina.tribes.membership.McastServiceImpl setupSocket
        INFO: Setting cluster mcast soTimeout to 500
        Apr 13, 2015 2:05:22 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
        INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:4
        Apr 13, 2015 2:05:23 PM org.apache.catalina.ha.tcp.SimpleTcpCluster memberAdded
INFO: Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp://{172, 20, 206, 149}:4100,{172, 20, 206, 149},4100,
alive=75105, securePort=-1, UDP Port=-1, id={-4 26 69 -5 -95 64 69 0 -91 5 37 -31 53 -32 55 122 }, payload={}, command={}, domain={}, ]

               tomcat集群防火墙设置成功后,再次启动tomcat,日志中出现问题

Apr 13, 2015 2:05:23 PM org.apache.catalina.tribes.group.interceptors.TcpFailureDetector memberAlive
SEVERE: Unable to perform failure detection check, assuming member down.
java.net.NoRouteToHostException: No route to host
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at org.apache.catalina.tribes.group.interceptors.TcpFailureDetector.memberAlive(TcpFailureDetector.java:327)
at org.apache.catalina.tribes.group.interceptors.TcpFailureDetector.memberAlive(TcpFailureDetector.java:312)
at org.apache.catalina.tribes.group.interceptors.TcpFailureDetector.memberAdded(TcpFailureDetector.java:133)
at org.apache.catalina.tribes.group.ChannelInterceptorBase.memberAdded(ChannelInterceptorBase.java:92)
at org.apache.catalina.tribes.group.ChannelInterceptorBase.memberAdded(ChannelInterceptorBase.java:92)
at org.apache.catalina.tribes.group.ChannelCoordinator.memberAdded(ChannelCoordinator.java:238)
at org.apache.catalina.tribes.membership.McastService.memberAdded(McastService.java:544)
at org.apache.catalina.tribes.membership.McastServiceImpl$2.run(McastServiceImpl.java:387)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
  • 相关概念资料引用

               1. 负载均衡(Load Balance):当同一客户端发起一个请求时,apache始终将请求转发到同一个节点 (sticky session),当另一个客户端或同一客户端从一个新的浏览器窗口发起请求时,apache会把请求分发到另一节点 上,依次轮询,当然,可以在apache上设置后端tomcat的分发权重。从而达到负载均衡的效果。

                2. 高可用(High availablity):当其中一台tomcat server 突然crash时,apache会将这在进行的请求分发到集群中其他tomcat server上,由于集群member 之间已经session replication,所以原来的session 会在另外一节点上继续进行,此时,请求已发生了无缝转移,在客户端完全感觉不到故障已发生。

          Tomcat 通过SimpleTcpcluster类进行基于内存的会话复制(in-memory replication)。Tomcat Cluster 通过组播(心跳包)方式决定组成员关系(通过TCP协议进行数据传输和其他交流),每一个节点在启动时和运行时都会有规律地(默认500毫秒)发送组播心跳包,同一个Cluster内的节点会在相同的组播地址和端口监听这些信息;在一定的dropTime内(默认3S)不发送组播报的节点就会被认为是死去并被从cluster删去;Session replication 请求和session 更新通过直接TCP 连接在cluster成员间传送,也就是说当replication session 时,节点会生成一个直接向其他节点的TCP连接。


 



  • 参考资料:

             说明网上实现tomcat集群配置内容不一,有的内容错误,有的内容残缺不全,使用时需要加以辨别

            http://m.oschina.net/blog/87469
            http://www.cnblogs.com/itech/archive/2009/08/18/1548723.html
            http://blog.****.net/bluishglc/article/details/6867358
            http://blog.****.net/maxracer/article/details/7207279
            http://blog.****.net/chaijunkun/article/details/6987443
            http://blog.sina.com.cn/s/blog_5f53615f0100p4fj.html
            http://www.ibm.com/developerworks/cn/opensource/os-lo-apache-tomcat/
            http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html
            http://blog.****.net/kobe_lzq/article/details/7047834
            http://blog.****.net/lifetragedy/article/details/7712691
            http://blog.****.net/lifetragedy/article/details/7707455

            http://blog.****.net/zhuying_linux/article/details/6590700#comments