基于mod_proxy+Apache 2.2.16+Tomcat 7的负载均衡与集群配置

基于mod_proxy+Apache 2.2.16+Tomcat 7的负载均衡与集群配置 Peter Wei转自【http://peterwei.iteye.com/blog/757125】

基于mod_proxy+Apache 2.2.16+Tomcat 7的负载均衡与集群配置

周日晚和GF的老乡们喝了五粮液,导致周一起不了床,只好请假在家睡觉。白天睡了半天,晚上自然睡不着觉。正好现在的项目中也用到了负载均衡和集群的东西,虽然有新手贴的危险,但还是手痒,决定写点东西,以备不时之需。也希望能对大家有所帮助。

第一章.背景简介

对于大多数企业应用,都希望能做到7*24小时不间断运行。要保持如此高的可用性并非易事,比较常见的做法是将系统部署到多台机器上,每台机器都对外提供同样的功能,这就是集群。系统变为集群时,除了要求系统能够支持水平伸缩外,还要解决两个问题:

1,如何均衡地访问到提供业务功能的机器。

2,如何保证当机器出现问题时,用户能自动跳转到另外的机器,不影响使用。

常用的负载均衡技术有硬件和软件两种,本示例常用软件的技术实现。软件也有很多实现技术,如基于apache的mod_jk以及mod_proxy等。基于mod_jk的文章有不少,本文演示一下用mod_proxy的方式。

实现集群的应用最重要的是处理用户Session的问题,一般有三种策略:

1,Session复制

2,SessionSticky

3,基于Cache的集中式Session

本文使用的是Tomcat7.0.2应用服务器,用的方法是Session复制。

第二章.配置环境

1,JDK1.6,请自行下载安装,搞Java的一般都装有的吧,哈哈。

2,Apache2.2.16,(released2010-07-25),现在为止应该是最新的稳定版本,下载地址:http://httpd.apache.org/download.cgi

3,Tomcat7.0.2,目前也是最新的版本。MinimumJavaVersion1.6.下载地址:http://tomcat.apache.org/download-70.cgi

4,安装过程略

第三章.部署图

第四章.Tomcat7集群配置

一、就地取材,复制tomcat7/webapps下的examples,重命名为cluster应用,以后就用cluster做测试。

二、详细配置参照tomcat7\webapps\docs\cluster-howto.html或者http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html

三、为了在Tomcat7中实现session复制,以下必需完成:

•所有session属性必需实现java.io.Serializable

•UncommenttheClusterelementinserver.xml。把Cluster元素的注释去掉。参照四

•Ifyouhavedefinedcustomclustervalves,makesureyouhavetheReplicationValvedefinedaswellundertheClusterelementinserver.xml。参照四

•IfyourTomcatinstancesarerunningonthesamemachine,makesurethetcpListenPortattributeisuniqueforeachinstance,inmostcasesTomcatissmartenoughtoresolvethisonit'sownbyautodetectingavailableportsintherange4000-4100。参照四<Receiver>中的注释

•Makesureyourweb.xmlhasthe<distributable/>elementorsetatyour<Contextdistributable="true"/>参照四

•Ifyouareusingmod_jk,makesurethatjvmRouteattributeissetatyourEngine<Enginename="Catalina"jvmRoute="node01">andthatthejvmRouteattributevaluematchesyourworkernameinworkers.properties.用mod_jk的情况,我们可以不管。

•MakesurethatallnodeshavethesametimeandsyncwithNTPservice!当使用多台机器时,要保证不同机器时间的同步。原因为tomcatsession复制的一些机制。具体原因看文档。

•Makesurethatyourloadbalancerisconfiguredforstickysessionmode.保证负载均衡软件设置为sessionsticky模式。

四、详细配置:

1.修改tomcat7_a/conf/server.xml,我们采用的是默认的配置,在<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"  
<!—tcpListenPort如果是同一机器部署两个tomcat7应用,则修改tomcat7_b为4001,以免冲突. 不同机器下,不用更改此项。—>  
                      [color=red]port="4000"[/color]  
                      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>  

2.<Connectorport="8081"protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"/>修改,仅为了调试方便。

3.tomcat7_a\webapps\cluster\WEB-INF\web.xml中加入<distributable/>

4.<Enginename="Catalina"defaultHost="localhost"jvmRoute="tomcat7_a">,添加jvmRoute属性,此项为后面apache负载均衡用到。

五、复制一份tomcat7_a应用,改名为tomcat7_b.只是为了图方便,实际应该复制的是前面的cluster工程。注意以下几点配置就ok.

1.修改tomcat7_a/conf/server.xml中的Serverport属性<Serverport="8006"shutdown="SHUTDOWN">,因为是同一台机器两个tomcat应用,所以改一下。

2.修改<connectorport="8082"protocol="HTTP/1.1"onnectionTimeout="20000"edirectPort="8443"/>,同理,为了避免同一台机器端口号冲突。部置在不同的机器是不用管的。

3.修改<Enginename="Catalina"defaultHost="localhost"jvmRoute="tomcat7_b">,此项为后面apache负载均衡用到。

4.修改<Receiverclassname="org.apache.catalina.tribes.transport.nio.NioReceiver"address="auto"port="4001"autoBind="100"selectorTimeout="5000"maxThreads="6"/>

5.tomcat7_b\ebapps\cluster\WEB-INF\web.xml中加入<distributable/>

到此集群配置完成.

第五章.集群测试

1.tomcat7_a和tomcat7_b的cluster工程中分别添加测试文件:testCluster.jsp

<%@ page contentType="text/html; charset=GBK" %>  
<%@ page import="java.util.*" %>  
<html><head><title>Cluster Test</title></head>  
<body>  
<%  
  //HttpSession session = request.getSession(true);  
  System.out.println(session.getId());  
  out.println("<br> SESSION ID:" + session.getId()+"<br>");    
  // 如果有新的请求,则添加session属性  
  String name = request.getParameter("name");  
  if (name != null && name.length() > 0) {  
     String value = request.getParameter("value");  
     session.setAttribute(name, value);  
  }    
    out.print("<b>Session List:</b>");    
    Enumeration<String> names = session.getAttributeNames();  
    while (names.hasMoreElements()) {  
        String sname = names.nextElement();   
        String value = session.getAttribute(sname).toString();  
        out.println( sname + " = " + value+"<br>");  
        System.out.println( sname + " = " + value);  
   }  
%>  
  <form action="testCluster.jsp" method="post">  
    名称:<input type=text size=20 name="name">  
     <br>  
    值:<input type=text size=20 name="value">  
     <br>  
    <input type=submit value="提交">  
   </form>  
</body>  
</html>  

2.启动tomcat7_a,启动完毕后,启动tomcat7_b

3.进入http://localhost:8081/cluster/testCluster.jsp对应tomcat7_a(8081),登录几次,可看到

4.另外打开一个浏览器,进入http://localhost:8082/cluster/testCluster.jsp对应tomcat7_b(8082),登录name:tomcat_b,value:bvalue可看到

5.刷新tomcat7_a(8081)相关页面,可以看到从tomcat7_b提交的值session同步过来了,说明集群成功。

第六章.Session集群工作步骤

参照tomcat7doc:

Tomakeiteasytounderstandhowclusteringworks,Wearegonnatakeyouthroughaseriesofscenarios.InthescenarioweonlyplantousetwotomcatinstancesTomcatAandTomcatB.Wewillcoverthefollowingsequenceofevents:

1.TomcatAstartsup

2.TomcatBstartsup(WaitthatTomcatAstartiscomplete)

3.TomcatAreceivesarequest,asessionS1iscreated.

4.TomcatAcrashes

5.TomcatBreceivesarequestforsessionS1

6.TomcatAstartsup

7.TomcatAreceivesarequest,invalidateiscalledonthesession(S1)

8.TomcatBreceivesarequest,foranewsession(S2)

9.TomcatAThesessionS2expiresduetoinactivity.

第七章.负载均衡配置

Tomcat有两种负载均衡的方式:

1.使用JK1.2.xnativeconnector

2.使用ApacheHTTPServer2.xwithmod_proxy

我们使用的是mod_proxy,在ApacheHttpServer2.2以上版本已经自动带有:

Mod_proxysupportseitherHTTPorAJPloadbalancing.我们通过ajp方式。

详细查看:tomcat7\webapps\docs\balancer-howto.html

1.首先,监听8000端口,在Apache安装目录下找到conf/httpd.conf文件

稍前面加上

# 监听端口和监听地址  
Listen 8000  

2.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   

3.conf/httpd.conf文件最后加上:

#虚拟机配置,负载均衡配置  
<VirtualHost *:8000>  
    ServerAdmin [email protected]  
    ServerName localhost  
    ServerAlias localhost  
    #小心,有些地方要有空格,要不然会出错哈哈。  
    ProxyPass / balancer://cluster/ stickysession=JSESSIONID|jsessionid nofailover=On  
    ProxyPassReverse / balancer://cluster/  
    #ErrorLog "logs/error.log"  
    #CustomLog "logs/access.log" common  
</VirtualHost>   
  
#The ProxyRequests directive should usually be set off when using ProxyPass.  
ProxyRequests Off  
<proxy balancer://cluster>  
    BalancerMember ajp://localhost:8009 loadfactor=1 route=tomcat7_a  smax=5 max=20 ttl=120 retry=300 timeout=15  
    BalancerMember ajp://localhost:9009 loadfactor=1 route=tomcat7_b  smax=5 max=20 ttl=120 retry=300 timeout=15  
    # status=+H为配置热备,当所有机器都over时,才会请求该机器  
    #BalancerMember http://192.168.1.218:8009 status=+H  
    ProxySet lbmethod=bytraffic  
</proxy>  
4. Tomcat7配置(server.xml): 

因为是同一机器,两个应用,所以配不同的端口,不同机器则不用配,要和前面的ajp对应上。

<Connectorport="8009"protocol="AJP/1.3"redirectPort="8443"/>

<Connectorport="9009"protocol="AJP/1.3"redirectPort="8443"/>

第八章.负载均衡测试

Tomcat7_a的cluster工程的测试文件:testCluster.jsp加上html代码:

<b>负载均衡测试:此为:Tomcat7_a上的文件,<fontcolor=red>aaaaaaaaaaaaaaaaaa</font><b>

Tomcat7_b的cluster工程的测试文件:testCluster.jsp加上html代码

<b>负载均衡测试:此为:Tomcat7_b上的文件,<fontcolor=red>bbbbbbbbbbbbbbbbbb</font><b>

打开浏览器,进入地址:http://localhost:8000/cluster/testCluster.jsp

多刷新几次,会看到页面值会在aaaaa和bbbbb间切换,说明负载均衡配置成功。如图:

第九章.Mod_proxy负载均衡算法

目前mod_proxy有3种负载均衡算法:

1.RequestCounting(我猜是Round-robin),lbmethod=byrequests

2.WeightedTrafficCounting(这个是按权重,此例也是用此算法),lbmethod=bytraffic

3.PendingRequestCounting(从apche文档来看,应该是按负载量,也就是往负载少的派发新请求).lbmethod=bybusyness

它们通过lbmethod值设置。

第十章.参考文档:

Tomcat7doc文档

http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html

http://httpd.apache.org/docs/2.2/mod/mod_proxy.html

第十一章.补充内容:负载均衡管理器

负载均衡管理器可以动态更新负载均衡的应用,你可以用管理器更改负载因子或者特定的应用,还可以把应用设为off模式。

为了使用balancermanagement,mod_status和mod_proxy_balancer必需要加载到apache.

设置:

#此项为mod_proxy_balancer管理器需要

LoadModulestatus_modulemodules/mod_status.so

在负载均衡项前加上:

#mod_balancer管理应用

<Location/balancer-manager>

SetHandlerbalancer-manager

OrderAllow,Deny

Allowfromall

</Location>

可以通过以下地址访问:http://localhost:8000/balancer-manager

附件中是一些相关的配置文件,大家可以参考:

  • cluster_loadbalance.rar (15.7 KB)
  • 下载次数: 1206
  • 查看图片附件

相关推荐