apache+tomcat+mod_jk做负载均衡

最近做一个网站项目,需要考虑tomcat负载均衡问题,以下是我的总结.

 

1          环境

       Tomcat6(4个)

       Apache2.2

       mod_jk-1.2.30-httpd-2.2.3.so

2          原理简述

 


Apache是http服务器,负责接收http请求。如何将请求分发给后台tomcat 呢,这就需要mod_jk了,mod_jk是Apache用来链接tomcat的模块。它需要配置在Apache中。下面描述的是他们各自的分工情况

 

Apache要做的:Apache默认处理接收到的所有http请求,但可通过配置将请求转发给某个模块处理,并将模块处理结果返回,在这里我们将所有请求都转发给mod_jk去处理。

 

Mod_jk要做的:

 

a)      登记所有的tomcat服务器,并针对不同功能划分的tomcat做不同的配置。

b)     将从Apache接收到的请求按策略分配给tomcat。分配策略如下:

                          i.          对于新的会话按配置比例分发给tomcat

                         ii.          对于已有会话(http中包含session信息)的请求会发送给创建该会话的tomcat

                        iii.          当创建会话的tomcat无法响应时,发送给该tomcat指定的备份tomcat。如果没有指定,则视为新会话处 理。

 

Tomcat要做的:处理mod_jk发送过来的请求并返回结果。之前提到如果某一tomcat无法响应转由其他tomcat处理时,原有的session信息将会丢失。为解决此问题,于是就有了session同步的概念,即多个服务器之间共享session,当某一服务器不同提供服务时不会导致用户session丢失。Tomcat的session共享是基于ip组播协议实现的。(http://blog.csdn.net/wu_jietian/archive/2010/04/13/5480010.aspx )这里只需要知道session同步是可以通过配置实现的,并且是由Tomcat实现的而非mod_jk。至于具体细节请参考另一篇文章(http://blog.csdn.net/wu_jietian/archive/2010/04/13/5479990.aspx

 

       了解了原理之后,配置起来就水到渠成了。

 

3          约束

代码必须符合以下几点要求:

1.session 中的 attribute必须继承java.io.Serializable

2.程序中如果存在全局变量,需要考虑多个Tomcat间变量同步的问题。


 

4          部署

a)     安装tomcat、apache2.2 略。 网上资料大把,不再重复。

注意事项:apache需要设置最大并行连接数,不同的操作系统配置的方式不同,因为不同的系统使用的是不同的多路处理模块。配置视情况而定。


 

b)     安装并配置mod_jk

                 i. 安装mod_jk:

把下载的 mod_jk-1.2.28-httpd-2.2.3.so 改名为 mod_jk2.so 放到apache的modules目录下。

修改apache的conf目录下的httpd.conf,在文件最后加入一行include conf/mod_jk2.conf,在conf目录下创建mod_jk2.conf文件,内容如下:


 # 加载 mod_jk Module

LoadModule jk_module modules/mod_jk-1.2.30-httpd-2.2.3.so

# 指定  workers.properties 文件路径

JkWorkersFile conf/workers.properties

# 指定 log 目录

JkLogFile logs/mod_jk2.log

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

JkMount /* controller

 

 ii.配置mod_jk:


worker.list = controller,tomcat4,tomcat3,tomcat2,tomcat1

#server 列表 tomcat1-tomcat4 命名必须与 tomcat 配置文件 server.xml 中的 jvmRoute 相对应

 

#========tomcat1========

worker.tomcat1.port=8009

#ajp13 端口号,在 tomcat server.xml 配置 , 默认 8009

worker.tomcat1.host=localhost

#tomcat 的主机地址,如不为本机,请填写 ip 地址

worker.tomcat1.type=ajp13

worker.tomcat1.lbfactor = 1

#server 的加权比重,值越高,分得的请求越多

worker.tomcat1.redirect = tomcat2

# 指定 tomcat1 无法提供服务后由 tomcat2 继续提供服务

 

 

 

#========tomcat2========

worker.tomcat2.port=8010   

#ajp13 端口号,在 tomcat server.xml 配置 , 默认 8009

worker.tomcat2.host=localhost

#tomcat 的主机地址,如不为本机,请填写 ip 地址

worker.tomcat2.type=ajp13

worker.tomcat2.lbfactor = 1

#server 的加权比重,值越高,分得的请求越多

worker.tomcat2.redirect = tomcat1

# 指定 tomcat2 无法提供服务后由 tomcat1 继续提供服务

worker.tomcat2.activation = d

# 指定 tomcat2 只接收属于它的 session 的请求,隐含意思是新的请求不会发给 tomcat2

# 如果 tomcat1 tomcat2 实现 session 共享且 tomcat1 挂掉时, tomcat2 可以且只能为 session 属于 tomcat1 的请求提供服务。(可能比较绕,需要费几个脑细胞)

#========tomcat3========

worker.tomcat3.port=8011

#ajp13 端口号,在 tomcat server.xml 配置 , 默认 8009

worker.tomcat3.host=localhost

#tomcat 的主机地址,如不为本机,请填写 ip 地址

worker.tomcat3.type=ajp13

worker.tomcat3.lbfactor = 1

#server 的加权比重,值越高,分得的请求越多

worker.tomcat3.redirect = tomcat4

 

 

 

#========tomcat4========

worker.tomcat4.port=8012   

#ajp13 端口号,在 tomcat server.xml 配置 , 默认 8009

worker.tomcat4.host=localhost

#tomcat 的主机地址,如不为本机,请填写 ip 地址

worker.tomcat4.type=ajp13

worker.tomcat4.lbfactor = 1

#server 的加权比重,值越高,分得的请求越多

worker.tomcat4.redirect = tomcat3

worker.tomcat4.activation = d

 

#========controller, 负载均衡控制器 ========

worker.controller.type=lb

worker.controller.balanced_workers=tomcat4,tomcat3,tomcat2,tomcat1   # 指定分担请求的 tomcat

worker.controller.sticky_session=1

 

c) 配置tomcat

                 i.  <Server port="8005" shutdown="SHUTDOWN"> 果是同一台电脑,port不能重复

 

        ii.  <Engine name="Catalina" defaultHost="localhost"> 改为<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1-4">

                iii. 设置session共享,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"

                     

                      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>

 

 Port需要特殊说明:address 和port都相同的tomcat视为一个集群,session共享是发生在集群内部的,因此这里我们 将tomcat1,2为一组及port=45564,tomcat3,4为一组port=45565。

              iv. 在tomcat中添加应用testGroup,在其根目录下增加index.jsp文件,index.jsp内容如下

 

<%

   session.setAttribute("session1","session1");

//tomcat2 的则改为    session.setAttribute("session2","session2"); 以此类推

 

   System.out.println("===========================");

   System.out.println(session.getAttribute("session1"));

   System.out.println(session.getAttribute("session2"));

   System.out.println(session.getAttribute("session3"));

   System.out.println(session.getAttribute("session4"));

   System.out.println("sessionId =  " + session.getId());

%>

 

<html>

  <body >

    <center>

<h1>Tomcat 1</h1>

<!--tomcat2 的则改为    Tomcat 2 以此类推 -->

  </body>

</html>

               v.在web.xml加入 <distributable/>  即可

<web-app xmlns="http://java.sun.com/xml/ns/javaee"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

   version="2.5">

<distributable/>

  <display-name>testGroup</display-name>

</web-app>

 

5        测试

启动tomcat1-4 再启动apache

a)反复重启浏览器访问http://127.0.0.1/testGroup   你会发现只有tomcat1和tomcat3 接收到的请求。(注意tomcat控制台打印信息)

 

b) 访问http://127.0.0.1/testGroup ,比如当前页面显示是tomcat1,此时关闭tomcat1,刷新页面,页面应该显示为tomcat2.并且tomcat2后台打印信息应为

 

==========

session1

session2

null

null

 

你会发现tomcat1,2之间实现了session共享

 

c)之后反复重启浏览器访问,你会发现页面显示的都是tomcat3,因为tomcat1挂了,tomcat2,4不接受新请求

 

 

 

 

总结完毕

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值