结合Apache和Tomcat实现集群和负载均衡

来源:互联网 发布:怎么用淘宝优惠券赚钱 编辑:程序博客网 时间:2024/06/10 04:58

转载于:http://lishaofengstar.blog.163.com/blog/static/131972852201212782537395/

在实际应用中,如果网站的访问量很大,为了提高访问速度,可以与多个Tomcat服务器与Apache服务器集成,让他们共同运行servlet/jsp组件的任务,多个Tomcat服务器构成了一个集群(Cluster)系统,共同为客户提供服务。集群系统具有以下优点:
高可靠性(HA):利用集群管理软件,当主服务器故障时,备份服务器能够自动接管主服务器的工作,并及时切换过去,以实现对用户的不间断服务。  
高性能计算(HP):即充分利用集群中的每一台计算机的资源,实现复杂运算的并行处理,通常用于科学计算领域,比如基因分析,化学分析等。  
负载平衡:即把负载压力根据某种算法合理分配到集群中的每一台计算机上,以减轻主服务器的压力,降低对主服务器的硬件和软件要求。  
原理:JK插件的负载均衡器根据在worker.properties中配置的lbfactor(负载平衡因数),负责为集群系统中的Tomcat服务器分配工作负荷,以实现负载平衡。每个Tomcat服务器间用集群管理器(SimpleTcpCluster)进行通信,以实现HTTP回话的复制,比如Session。
Apache+Tomcat集群配置详解 - 湘雅之梦 - nbsp爱的天空
下面我们在一台机器上配置一个Apache和两个Tomcat服务器集群:
1.准备:Apache  Tomcat  JK插件,下载地址详见:http://lishaofengstar.blog.163.com/blog/static/131972852201212694624295/
2.安装Apache,安装两个Tomcat,并把一个测试项目放到两个Tomcat的webapps目录下以便以后测试。
3.把mod_jk.so复制到<apache_home>/modules下。
4.在<apache_home>/conf目录下创建:workers.properties文件:

worker.list= worker1,worker2,loadbalancer        #apache把Tomcat看成是工人,loadbalancer是负载均衡器

 
worker.worker1.host=localhost        #Tomcat worker1服务器
worker.worker1.port=8009            #Tomcat端口
worker.worker1.type=ajp13            #协议
worker.worker1.lbfactor=100            #负载平衡因数
 
worker.worker2.host=localhost        #Tomcat worker2服务器
worker.worker2.port=8009            #因为在一台机器上所以端口不能一样
worker.worker2.type=ajp13            #协议
worker.worker2.lbfactor=100            #设为一样代表两台机器的负载相同
 
worker.loadbalancer.type=1b
worker.loadbalancer.balanced_workers=worker1,worker2
worker.loadbalancer.sticky_seesion=false
worker.loadbalancer.sticky_session_force=false
说明:1.worker.loadbalancer.sticky_seesion如果设为true则说明会话具有“粘性”,也就是如果一个用户在一个Tomcat中建立了会话后则此后这个用户的所有操做都由这个Tomcat服务器承担。集群系统不会进行会话复制。如果设为false则下面的 sticky_session_force无意义。
2.sticky_session_force:假设sticky_session设为true,用户会话具有了粘性,当当前Tomcat服务器停止服务后,如果sticky_session_force为true也就是强制会话与当前Tomcat关联,那么会报500错误,如果设为false则会转到另外的Tomcat服务器。
 
5.修改<apache_home>/conf/httpd.conf文件,在文件后面加上:
#Tomcat集群配置
LoadModule jk_module modules/mod_jk.so
#JK插件的位置 
JkWorkersFile conf/workers.properties
#我的工人们
JkLogFile logs/mod_jk.log            
#日志文件
JkLogLevel debug                     
#tomcat运行模式
JkMount /*.jsp loadbalancer          
#收到.jsp结尾的文件交给负载均衡器处理
JkMount /helloapp/* loadbalancer     
#收到helloapp/路径交给负载均衡器处理
6.修改两个Tomcat的conf/service.xml文件。
6.1首先要修改AJP端口,确保他们与workers.properties中配置的一样
例如按我们上面的配置,只需要把Tomcat2中的AJP端口该为8109即可。
6.2此外在使用了loadbalancer后,要求worker的名字与Tomcat的service.xml中的Engine元素的jvmRoute属性一致,
例如worker1修改为: <Engine name="Catalina" defaultHost="localhost" jvmRoute="worker1">
6.3另外,如果两台Tomcat服务器装在一台机器上,必须确保他们的端口没有冲突,Tomcat中一共配置了三个端口:
<Server port="8005" shutdown="SHUTDOWN">
<Connector port="8080" .../>
<Connector port="8109" protocol="AJP/1.3" redirectPort="8443" />
把其中一个该了让它们不一样就行了。
 
完成了以上步骤我们的集群算是基本完成了,打开Apache和两个Tomcat 浏览器进入:localhost/demo/ 能够正确访问。
为了测试,我们写一个jsp文件:test.jsp

<html>

<head>
<title>test</title>
</head>
<body>
    <%
        System.out.printfln("call test.jsp");
    %>
    session:<%=session.getId() %>
</body>
</html>

把它放到两个Tomcat中的demo项目中,浏览器访问这个页面,每次访问只在一个Tomcat控制台打印语句。

然而页面中的Session Id是会变的。这种情况下如果一个用户正在访问时,如果跳到另一个Tomcat服务器,那么他的session就没有了,可能导致错误。
 
7.配置集群管理器
如果读者对HttpSession有了解应该知道,用户的会话状态保存在session中,一个浏览器访问多个网页它们的请求始终处于一个会话范围中,因此SessionID应该是不变的。
以上我们看到的浏览器中的SessionID不同,因为转到另一个Tomcat后当前会话就结束了,又在另一个服务器上开启了一个新的会话。那么怎么让多个Tomcat服务器共享一个会话呢?
为了解决上述问题,我们启用Tomcat的集群管理器(SimpleTcpCluster):
7.1修改Tomcat1和Tomcat2的servlet.xml文件,在Engine元素中加入以下Cluster元素
<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"
                        bind="127.0.0.1"
                        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=""/>
        <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> 
关于Cluster的相关介绍参照:<tomcat-home>\webapps\docs\cluster-howto.html  <tomcat-home>\webapps\docs\config\cluster.html
7.2分别修改Tomcat1和Tomcat2 demo项目的web.xml文件,在后面加入<distributable>元素
<web-app>
...
<distributable/>
</web-app>
如果一个web项目的web.xml文件中指定了<distributable/>元素那么Tomcat服务器启动这个Web应用时,会为它创建由<Cluster>元素指定的会话管理器,这里我们用的是DeltaManager,他们把会话从一个Tomcat服务器复制到集群中另一个Tomcat服务器。
7.3重新启动两个Tomcat,发现Tomcat控制台还是依次打印出Call test.jsp 页面中的SessionID却不变了。测试完成。
重要说明:(1).如果项目要发布到集群上,那么与会话有关的类需要实现java.io.Serializable序列化接口。
(2).集群中Tomcat间用组播方式进行通信,如果机器上有多个网卡则可能导致组播失败,解决的办法是<Cluster>元素的<Membership>元素配置bind属性,它用于明确知道组播地址:
<Membership className="org.apache.catalina.tribes.membership.McastService" bind="127.0.0.1".../>
(3).如果集群较小,可以采用DeltaManager会话管理器,如果多的话建议使用BackupManager
(4).<Membership>的address设为"228.0.0.4",运行时须确保机器联网能访问到该地址,否则可能运行失败。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 顺产后恶露白色异味怎么办 产妇排出的恶露有异味怎么办 恶露有股腥臭味怎么办 生完孩子下面有异味怎么办 销售货物开票税率错了怎么办 8h床垫有橡胶味怎么办 买回来的鞋子臭怎么办 耐克保修卡没了怎么办 雅萌保修卡没了怎么办 苹果保修卡没了怎么办 新车迟迟不给合格证怎么办 手机系统剩余空间少怎么办 桌子被掉色的袋子印色怎么办 袋子掉色弄到柜子上怎么办 健身房老板跑路教练怎么办 健身房老板跑路了怎么办 淘宝断货了该怎么办 淘金猫网购频道账号换了怎么办 京东商城信用卡无法付款怎么办 京东第三方退货拒收怎么办 淘宝凑单收货地址不一样怎么办 淘宝凑单地址不一样怎么办 任性付还不了款怎么办 京东购物卷删了怎么办 荣耀手环3进水了怎么办 手机疏油层没了怎么办 快递到了处理中心不走了怎么办 京东取消了退款怎么办 我的订单删除了怎么办 近邻宝箱子误关怎么办 把收件人电话写错了怎么办 吧收件人电话写错了怎么办 速递易收件人电话写错怎么办 书包上的皮掉了怎么办 美亚很多商品不直邮中国怎么办 我想买刘涛用的化妆品贵妇膏怎么办 自提柜号码忘记了怎么办 京东商城误点确认收货怎么办 京东购物到货后怎么办 京东地址错了怎么办 没买运费险退货怎么办