Apache + Tomcat 实现负载均衡


在北京工作已经也有了两年的时间,做过质量管理软件,做过金融,现在又做到了互联网。看看blog好久没有自己写点东西了,不像刚开始接触java的时候每天还会写点东

西,可能是懒了,也可能觉得自己写得东西不一定会给别人带来帮助......我不是一个善于面试的人,因为我的基础不好,java也是自己看着视频学得,其他的东西都是在工作中学得

总觉得面试的时候有点力不从心。。。


今天写得东西就是关于面试的时候一个面试人员问我的问题。用过apache么?我说没用过。用过tomcat么?我说用过。apache+tomcat如何实现负载均衡?不知道。。。

又是一问三不知。回来自己看了看网上的文章自己搞了搞。勉强算是搞起来了。下面就写出来。希望和我一样的人能可以搞出来点东西,学到一点自己想学得东西。


我的环境用得是apache2.2 + tomcat 7 负载均衡器为:mod_jk 具体的下载链接我也忘记了。。。。baidu就好了。 下面我们开始搭配环境。


1.安装apache。

2.我是apache挂了3个tomcat。所以下载tomcat的时候最好是zip形式的。解压出来,这样比较方便。解压3个tomcat分为别tomcat1,tomcat2,tomcat3

3.找到apache的所在目录,在conf文件夹下找到httpd.conf这个配置文件。打开这个配置文件,定位到最后一行加入如下代码:

Include conf/mod_jk.conf

如图:


这里的路径也可以写为绝对路径,网上也有得资料写得是绝对路径,但是我测试的时候写成这样也可以我就写成了这个样子。

4.在conf文件夹下建立mod_jk.conf文件。建立完成后加入如下代码:

LoadModule jk_module modules/mod_jk.so
JkWorkersFile conf/workers.properties
#制定哪些请求交给tomcat处理,"controller"为在workers.properties里制定的负载分配器名
JkMount /*.* controller

如图:

里面的含义我想大概看下应该就会明白,具体我也没有深究,个人觉得 

LoadModule jk_module modules/mod_jk.so 含义:指定加载Module为jk_module 路径在modules下得mod_jk.so文件

JkWorkersFile conf/workers.properties 指定workers的配置文件的所在位置为conf下得workers.properties

JkMount /*.* controller 为指定哪些请求交给tomcat进行处理,这个controller为workers.properties里面指定的负载分配器名字。这里有一个需要大家注意的地方,

我再测试的时候写得是*.jsp,这样凡是jsp为结尾的访问方式都会交给tomcat进行处理。但是这里会有一个问题,当你的页面上面带有图片的时候是无法显示的

,而且页面上面加载的*.js,*.css也是无法加载的,这是为什么呢?个人觉得原因是,配置的只是*.jsp交给tomcat进行处理,而图片啊,js的结尾为*.jpg,*.js等

apache没有转发给tomcat,而是在自己的路径下找没有找到相应的图片和js,所以加载不成功。解决这个问题的方法为:1.和我上面的方法一样配置*.*全部交给

tomcat进行处理,但是我觉得这样的方式肯定不是主流的方式,因为这样在你每个项目下的tomcat都要有相应的东西。2.我认为可以把这些东西放到apache下

tomcat只是处理解析动态的代码也就是jsp,这样问题应该就相应解决了。因为我也是初学有得地方不一定对,希望看到我的文章的朋友如果是大牛可以对我进行

一下指导,如果是和我一样初学的人可以一起研究。

5.配置完上面的东西我们需要在到conf目录下创建一个workers.properties文件。文件中的内容为:

#server
worker.list = controller

#=========tomcat1=======
worker.tomcat1.port=11009
worker.tomcat1.host=localhost
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor=1
#=========tomcat2=======
worker.tomcat2.port=12009
worker.tomcat2.host=localhost
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor=1
#=========tomcat3=======
worker.tomcat3.port=13009
worker.tomcat3.host=localhost
worker.tomcat3.type=ajp13
worker.tomcat3.lbfactor=1
#=========tomcat4=======
##可以设置远程服务器,设置方法host为ip地址
#===========controller,负载均衡控制器====
worker.controller.type=lb
worker.controller.balanced_workers=tomcat1,tomcat2,tomcat3
worker.controller.sticky_session=false
worker.controller.sticky_session_force=1
worker.controller.sticky_session=1

如图:


值得注意的是这里的controller要与mod_jk.conf中配置的名字一样。下面为配置tomcat我的3个tomcat都在本地,如果tomcat有一个

远程服务器只需要将host变为ip地址即可。

worker.tomcat3.type=ajp13指定worker tomcat3的通讯方式为ajp13

worker.tomcat3.lbfactor=1为指定权重,值越大处理的时候分到的请求就越多。

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

worker.controller.sticky_session=1 表述是否将对session id的请求路由回到相同的tomcat worker,如果属性值不为0,它将被设置为jk_true

session将是粘性的,即session id的请求路由回到相同的tomcat worker。当tomcat正使用能够跨越多个tomcat实例持久化session数据的

session manager的时候,她将被设置为jk_false 属性默认为jk_true;


6.配置好上面以后将下载好的 “tomcat-connectors-1.2.32-windows-i386-httpd-2.2.x”中得mod_jk放到apache目录中得modules下。

注意选择这个connectors文件的时候需要和你的apache版本要匹配不然会出现问题。


7.下面我们来修改tomcat的配置文件。到tomcat/conf文件夹中修改server.xml文件。

如图:


此处需要注意的是。这个AJP/1.3的port的端口号要和你的worker配置文件中得端口号相同,此端口号最大支持5位。多了会报错,

而且还需要保持Http/1.1的端口号不能重复。不然的话不能挂载的tomcat同时启动。还有jvmRoute的的参数为worker中配置的。


做完上面的工作我们的环境基本算是搭建成功了。下一步就是进行测试了。

建立一个test项目,分别放到你挂的几个tomcat下。

建立一个test.jsp内容为:

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<html>
  <head>
    <title>Cluster App Test</title>
  </head>
  <body>
    Server Info:
    <% out.println(request.getLocalAddr()+" : "+request.getLocalPort()+"<br>"); %>
    <% out.println("<br>ID "+session.getId()+"<br>"); 
    //如果有新的Session属性设置
    String dataName = request.getParameter("dataName");
    if(dataName!=null && dataName.length()>0){
    	String dataValue = request.getParameter("dataValue");
    	session.setAttribute(dataName,dataValue);
    }
    out.println("<b>Session列表</b><br>");
    System.out.println("===========");
    Enumeration e = session.getAttributeNames();
    while(e.hasMoreElements()){
    	String name = (String)e.nextElement();
    	String value = session.getAttribute(name).toString();
    	out.println(name+"="+value+"<br>");
    	System.out.println(name+"="+value);
    }
    %>
    
    <form action="test.jsp" method="post">
    	名称:<input type="text" size="20" name="dataName">
    	<br>
    	值:<input type="text"size="20"name="dataValue">
    	<br>
    	<input type="submit">
    </form>
  </body>
</html>
同时修改web.xml添加<distributable/>


然后启动apache,与tomcat访问页面看结果喽。。。。。。希望大家可以成功。
大笑


ps:菜鸟一只,如果有不对的地方希望大牛指点与提携。


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="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"/>
                        <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
                </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>


发布了49 篇原创文章 · 获赞 7 · 访问量 41万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章