我的日常

登录/注册
您现在的位置:论坛 盖世程序员(我猜到了开头 却没有猜到结局) 运维优化 > Tomcat6 配置集群和Apache2负载均衡配合详解
总共48086条微博

动态微博

查看: 2380|回复: 0

Tomcat6 配置集群和Apache2负载均衡配合详解

[复制链接]
admin    

1244

主题

544

听众

1万

金钱

管理员

  • TA的每日心情

    2021-2-2 11:21
  • 签到天数: 36 天

    [LV.5]常住居民I

    管理员

    跳转到指定楼层
    楼主
    发表于 2014-07-16 19:54:09 |只看该作者 |倒序浏览
    Tomcat6 配置集群和Apache2负载均衡
    环境
    apache-tomcat-6.0.28 两个,分别为tomcat1、tomcat2。下文中如果没特指tomcat1还是tomcat2,那么tomcat1和tomcat2都要进行操作。
    apache2.2 一个。
    tomcat集群修改tomcat Engine
    打开tomcat下conf/server.xml文件,找到 <Engine name="Catalina" defaultHost="localhost">,增加jvmRoute属性,以支持AJP负载均衡。
    tomcat1改为<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">。
    tomcat2改为<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm2">。
    修改tomcat 2端口配置
    由于tomcat1和tomcat2在同一台机器上,所以为了防止端口冲突,其中的一个 tomcat相关端口需要修改。在这里修改tomcat2。
    打开tomcat下conf/server.xml文件,修改如下:
    <Server port="8005" shutdown="SHUTDOWN">修改为<Server port="9005" shutdown="SHUTDOWN">。
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />修改为 <Connector port="9080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="9443" />。
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />修改为 <Connector port="9009" protocol="AJP/1.3" redirectPort="9443" />。
    提示:tomcat在不同机器上,此步骤可省略。


    集群和Session复制
    打开tomcat下conf/server.xml文件,在tomcat <Engine></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="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=" .\.gif;.\.js;.\.jpg;.\.png;.\.css;.\.txt; "/>
    <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>

    其中同台机器上的TCP Port不要冲突,TCP Port CulsterChannelReciver的port属性,默认为4000,tomcat识别的范围为4000-4100,这里把tomcat2 TCP Port改为4001。
    应用程序支持集群
    在应用程序web.xml中加入<distributable/>元素使应用程序支持集群,即Web应用是以这样的方式编程的:支持集群的服务器可安全地在多个服务器上分布Web应用。或者打开tomcat下conf/context.xml文件,修改<Context >为<Context distributable="true"> ,让tomcat发布的应用程序支持集群。
    这里采取修改<Context>方法。
    context复制
    对context添加一个实现类即可实现context复制,打开tomcat下conf/context.xml文件,修改<Context>为
    <Context className="org.apache.catalina.ha.context.ReplicatedContext">

    如果我们之前已经修改了<Context>为<Context distributable="true">,需要再添加上distributable="true"这个属性。
    测试Tomcat集群
    在tomcat/webapps下,新建一文件夹为test,在test文件夹下建立test.jsp文件,文件内容,如下:
    <%@ page contentType="text/html; charset=UTF-8"%>
    < %@ page import="java.util.*" %>
    < html><head><title>Cluster App Test</title></head>
    < body>
    Server Info:
    < %
    out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
    < %
    request.setCharacterEncoding("UTF-8");
    out.println("<br> ID " + session.getId()+"<br>");
    String dataName = request.getParameter("dataName");

    if (dataName != null && dataName.length() > 0) {
    String dataValue = request.getParameter("dataValue");
    session.setAttribute(dataName, dataValue);
    }

    out.print("<b>Session 内容列表</b> <br>");

    Enumeration e = session.getAttributeNames();
    while (e.hasMoreElements()) {
    String name = (String)e.nextElement();
    String value = session.getAttribute(name).toString();
    out.println( name + " :" + value+"<br>");
    }
    %>
    <form action="test.jsp" method="POST" >
    名称:<input type=text size=20 name="dataName">
    <br>
    值 &nbsp&nbsp:<input type=text size=20 name="dataValue">
    <br>
    <input type=submit value="提交" >
    </form>
    < /body>
    < /html>

    这个简单的工程用来可以把提交的值保存到Session,并显示出来。启动tomcat1,等tomcat1启动完成后,启动tomcat2。先访问tomcat1对应的test工程test.jsp页面,输入值,并提交,然后把链接转到tomcat2对应的test工程test.jsp页面,看看session内容是否相同。如果相同则测试成功。
    Apache负载均衡
    打开并修改apache安装目录下conf/httpd.conf文件,找到这些行:
    #LoadModule negotiation_module modules/mod_negotiation.so
    #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

    去掉"#"。
    在文件最后加入:
    ProxyPass / balancer://cluster/ stickysession=JSESSIONID

    ProxyPassReverse / balancer://cluster/
    < proxy balancer://cluster>
    BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
    BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2
    < /proxy>

    重新启动apache,以apache作为负载均衡器的tomcat集群建立完成。
    tomcat集群和Session复制详解Cluster
    <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
    channelSendOptions="8">


    Tomcat集群的主元素,在Cluster元素里面配置了集群的详细信息。当前tomcat仅提供了org.apache.catalina.ha.tcp.SimpleTcpCluste作为唯一的实现类。下面是Cluster详细属性:
    属性
    描述
    className
    Cluste的实现类,当前org.apache.catalina.ha.tcp.SimpleTcpCluste作为唯一的实现类。
    channelSendOptions
    Session发送方式,默认值为:8。当消息通过SimpleTcpCluster发送时,用来决定如何发送信息。
    file:///C:/Users/user/AppData/Local/YNote/Data/qq57D9FF2695CBD92A0CA37197DDB53806/ba4faf0a62094fa7815db0ea13f28dc0/n-attachment.pngfile:///C:/Users/user/AppData/Local/YNote/Data/qq57D9FF2695CBD92A0CA37197DDB53806/ba4faf0a62094fa7815db0ea13f28dc0/n-attachment.pngfile:///C:/Users/user/AppData/Local/YNote/Data/qq57D9FF2695CBD92A0CA37197DDB53806/ba4faf0a62094fa7815db0ea13f28dc0/n-attachment.png
    int options= Channel.SEND_OPTIONS_ASYNCHRONOUS

    Channel.SEND_OPTIONS_SYNCHRONIZED_ACK
    Channel.SEND_OPTIONS_USE_ACK;


    Channel.SEND_OPTIONS_SYNCHRONIZED_ACK = 0x0004Channel.SEND_OPTIONS_ASYNCHRONOUS = 0x0008Channel.SEND_OPTIONS_USE_ACK = 0x0002

    如果使用异步(ASYNCHRONOUS)加应答(USE_ACK)方式来发送消息,那么值应该是10(8+2)或者0x000B。|
    Manager
    <Manager className="org.apache.catalina.ha.session.DeltaManager"
    expireSessionsOnShutdown="false"
    notifyListenersOnReplication="true"/>


    Manager用来在tomcat节点之前复制Session,当前有两个实现类,分别为:org.apache.catalina.ha.session.DeltaManager、org.apache.catalina.ha.session.BackupManager。DeltaManager调用SimpleTcpCluster.send方法来发送信息,复制并发送Session到集群下所有的节点,无论这个节点有没有部署当前程序。BackupManager通过自己直接调用channel来发送信息,复制并发送Session到集群下部署了当前程序的节点。
    DaltaManager的优点是经过实践确认和证明的,非常可靠,而BackupManager在可靠性上不如DaltaManager。DaltaManager缺点是要求集群节点必须部署了同样的程序,节点必须是同种类的。
    下面是Manager的属性:
    普通属性:
    属性
    描述
    className
    Manager的实现类。
    notifyListenersOnReplication
    如果设置为true,当session属性被复制和移动的时候,session listener被通知
    expireSessionsOnShutdown
    当一个web程序被结束时,tomcat分发销毁命令到每个Session,并通知所有session listener执行。当集群下某个节点被停止时,如果想销毁所有节点下的的Session,设置为true,默认为false 。

    BackupManager属性
    属性
    描述
    mapSendOptions
    BackupManager通过一个可复制的map来实现session接受和发送,通过设置mapSendOptions来设定这个map以何种方式来发送信息,默认为值:6(asynchronous)。

    Channel
    <Channel className="org.apache.catalina.tribes.group.GroupChannel">

    Channel是Apache Tribes的主组件,channel管理一组子组件,并和它们一起组成了tomcat实例间的通讯框架。在tomcat集群中,DeltaManager通过SimpleTcpCluster调用channel来实现信息传递,而BackupManager自己调用channel以及子组件这些组件来实现信息传递。ReplicatedContext也会调用channel传递context属性。
    下面是channel子组件:
    • MemberShip
    MemberShip组件自动检索发现集群里的新节点或已经停止工作的节点,并发出相应的通知。默认使用组播(Multicast)实现。
    • Sender
    Sender组件管理从一个节点发送到另外一个节点的出站连接和数据信息,允许信息并行发送。默认使用TCP Client Sockets。
    • Receiver
    Receiver组件负责监听接收其他节点传送过来的数据。默认使用non-blocking TCP Server sockets。
    • Interceptor
    Channel通过Interceptor堆栈进行消息传递,在这里可以自定义消息的发送和接收方式,甚至MemberShip的处理方式。
    Value
    <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
    filter=" .\.gif;.\.js;.\.jpg;.\.png;.\.css;.\.txt; "/>
    < Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

    Cluster下的Value同其他tomcat value一样,value在调用Http Request 链中起着拦截器的作用,用来决定什么情况下数据需要被复制。
    org.apache.catalina.ha.tcp.ReplicationValve,ReplicationValue在Http Request结尾判断当前数据是否需要被复制。
    属性
    描述
    className
    org.apache.catalina.ha.tcp.ReplicationValve,ReplicationValue
    filter
    Filter内容为url或者文件结尾,当访问链接配置filter时,不论实际session有没有改变,集群会认为session没有任何变化,从而不会复制和发送改变的session属性。Filter写法如下:filter=" .\.gif;.\.js;.\.jpg;.\.png;.\.css;.\.txt; "。filter使用正则表达式,每个url或者后缀以逗号分开。


    Deployer
    使集群支持farmed deployment。这个功能还很弱,在变化和更改中。
    ClusterListener
    <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
    <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
    </Cluster>


    Clusterlistener用来追踪信息发送和接收。
    JvmRouteSessionIDBinderListener用来监听session id的变化。这个listener仅当使用mod_jk并且属性有jvmRoute时才起作用。当session id 改变后,JvmRouteBinderValve将广播这个信息并被此listener捕获。
    ClusterSessionListener用来监听集群组件接收信息,当使用DeltaManager的时候,信息被集群接收,并通过ClusterSessionListener传递给Session Manager。
    Apache负载均衡详解
    ProxyPass / balancer://cluster/ stickysession=JSESSIONID

    ProxyPassReverse / balancer://cluster/
    < proxy balancer://cluster>
    BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
    BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2
    < /proxy>


    通过Apache自带的mod_proxy某块来使用代理技术连接tomcat, ajp_proxy需要tomcat提供ajp服务。


    科帮网 1、本主题所有言论和图片纯属会员个人意见,与本社区立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与科帮网享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和科帮网的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、科帮网管理员和版主有权不事先通知发贴者而删除本文


    JAVA爱好者①群:JAVA爱好者① JAVA爱好者②群:JAVA爱好者② JAVA爱好者③ : JAVA爱好者③

    红红火火恍恍惚惚
    快速回复
    您需要登录后才可以回帖 登录 | 立即注册

       

    关闭

    站长推荐上一条 /1 下一条

    发布主题 快速回复 返回列表 联系我们 官方QQ群 科帮网手机客户端
    快速回复 返回顶部 返回列表