Apache httpd与tomcat集群

Stella981
• 阅读 834

回顾

前几天,刚刚搭建了apache httpd的静态网站,并为其开启的SSL。http://my.oschina.net/xpbug/blog/197454

今天在其基础上,我们将使用tomcat搭建集群,并把httpd改造成一个load banlencer的逆向代理。

应用的开发

首先,我需要开发一个web应用,来测试我的集群,于是,我创建了一个动态web项目,取名叫sessiontest. 在此项目中,只有两个jsp文件。

第一个select.jsp. 这个文件相当于一个购物车,将用户选中的内容提交,并展示用户选中的物品。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <title>Your selections</title>
  </head>
  <body>
    <% 
    String selections = (String)session.getAttribute("selections");
    selections=selections==null?"":selections;
    %>
    <form action="successful.jsp" method="post">
      <p>What do you prefer?</p>
      <p><input type="checkbox" name="car" value="car" <%
        if(selections.indexOf("car")>-1) out.print("checked=\"checked\""); %> />Car</p>
      <p><input type="checkbox" name="bike" value="bike" <% 
        if(selections.indexOf("bike")>-1) out.print("checked=\"checked\""); %> />Bike</p>
      <p><input type="checkbox" name="train" value="train" <% 
        if(selections.indexOf("train")>-1) out.print("checked=\"checked\""); %> />Train</p>
      <p><input type="checkbox" name="plane" value="plane" <% 
        if(selections.indexOf("plane")>-1) out.print("checked=\"checked\""); %> />Plane</p>
      <input type="submit" value="Submit" />
    </form>
  </body>
</html>

第二个文件是successful.jsp, 它将select.jsp提交的选项包存入session中。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Successful</title>
</head>
<body>
<%
  StringBuffer sb = new StringBuffer();
  if (null !=request.getParameter("car"))sb.append("car;");
  if (null !=request.getParameter("bike"))sb.append("bike;");
  if (null !=request.getParameter("train"))sb.append("train;");
  if (null !=request.getParameter("plane"))sb.append("plane;");

  session.setAttribute("selections", sb.toString());
%>
Successful, please go back to check.<br>
<a href="select.jsp">Back</a>
</body>
</html>

将项目导出为sessiontest.war,并部署到tomcat中的用户界面为:

http://localhost:8080/sessiontest/select.jsp

Apache httpd与tomcat集群

http://localhost:8080/sessiontest/successful.jsp

Apache httpd与tomcat集群

接下来,我会使用这个web应用来测试我的集群。

最简单的集群

如下图所示,最简单的集群并不是一个真正的集群,tomcat1和tomcat2只是运行了同一个应用,比如我的sessiontest.war, 它们两个之间并没有任何通信,共享。Apache只是根据访问量进行负载平衡。一旦其中一个tomcat关机,所有的request都将被转发到另一个tomcat上去。而之前工作在第一个tomcat上的用户会丢失信息,比如session,运行环境。

Apache httpd与tomcat集群

  1. 首先在本机上安装两个tomcat, 也就是生成2分tomcat的copy。下面将这两个tomcat分别以tomcat1和tomcat2命名。

  2. 维持tomcat1的port的配置,但需要向其server.xml中添加一个属性 jvmRoute="node1":

    <Engine name="Catalina" defaultHost="localhost" jvmRoute="node1">
    
  3. 修改tomcat2的port的配置,并向其server.xml中添加一个属性 jvmRoute="node2":

    <Server port="8006" shutdown="SHUTDOWN">
    <Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"/>
    <Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="node2">
    
  4. 将之前的应用sessiontest.war分别部署到两个tomcat上。测试localhost:8080/sessiontest/select.jsp和localhost:8081/sessiontest/select.jsp。这样,集群的两个node就跑起来了。

  5. 配置apache httpd,开启负载平衡。基于上一篇文章配好的https://www.test0.com 的网站,我将把集群挂在这个网站下面,将下面的配置加入virtualhost中。不要忘记开启proxy_balancer module。

    <VirtualHost *:443>
       ServerName www.test0.com
       ProxyPass /sessiontest balancer://mycluster 
       <Proxy balancer://mycluster>
          BalancerMember ajp://127.0.0.1:8009/sessiontest loadfactor=1 route=node1
          BalancerMember ajp://127.0.0.1:8010/sessiontest loadfactor=1 route=node2
          ProxySet stickysession=JSESSIONID
          ProxySet lbmethod=byrequests
       </Proxy>
    </VirtualHost>
    

    stickysession的意义在于,一个用户可以根据其cookie中的jsessionid固定的访问一个tomcat,这样不会在两个tomcat之间跳来跳去而丢失运行信息和session。

开启集群节点之间的通信

接下来,我将开启tomcat1和tomcat2之间的通信,这样它们可以共享session和一些内存信息。一个正在tomcat1上访问的用户,因为tomcat1的关机而转移到tomcat2上,也不会丢失session信息了。

Apache httpd与tomcat集群

  1. 修改原web应用,在sessiontest的web.xml中添加一段。表明此应用需要在cluster之间进行同步。然后重新部署此应用。

    <distributable/>
    
  2. 分别修改tomcat1和tomcat2的server.xml,加入相同的一段代码。 Tomcat使用组播技术,使得各个node之间建立连接,唯一需要声明的是你的Recervier端口,在4000-4999之间任选一个。

            <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="4444"
                          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.ClusterSessionListener"/>
            </Cluster>
    
  3. 分别启动tomcat1和tomcat2.请等一个启动完再启动另一个。集群创建完毕。

  4. 为了测验集群,我将负载平衡的stickysession关掉。请注释掉配置中的ProxySet stickysession=JSESSIONID. 重启apache. 这时候用户的request会在tomcat1和tomcat2之间跳来跳去。

  5. 访问https://www.test0.com/sessiontest/select.jsp 你会发现即使request在两个tomcat之间跳来跳去,但购物车里的信息永远不会丢失。

待续

配置ldap认证和授权,并开发一个登录页面。http://my.oschina.net/xpbug/blog/198765

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这