Franky's LIFE

Anything... ...

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  53 随笔 :: 87 文章 :: 6 评论 :: 0 Trackbacks
综述
0.1 目标
配置一个可扩展、高可用、有负载均衡和错误恢复的 Tomcat 集群

0.2 许可协议
GNU Free Documentation License 允许任意转载,但请保持本文档的完整性如有修改,务请通知作者

1. 下载
1.1
Tomcat
1.2 Tomcat 会话复制库

2. 安装
2.1 第一个 Tomcat

    $tar vfxz jakarta-tomcat-4.1.27.tar.gz
    $cp -R jakarta-tomcat-4.1.27 /www/server/tomcat1

2.2 第二个 Tomcat
# 暂时不安装,等配置好的一个 Tomcat 后,直接复制得到副本,在副本的基础上修改得到

2.3 JK2
# 请参考
《Linux 下安装支持 JSP/PHP 的 WEB server》一文编译.

3. 配置
3.1 Apache 的 JK2 配置文件 workers2.properties
# 这个是 Apache 的 JK2 配置文件,位于 Apache 安装目录下的 conf 目录中,如果原来没有这个文件,新建一个
# 内容如下

$vi workers2.properties
    [shm]
    file=${serverRoot}/logs/shm.file
    size=1048576
 
    # First Tomcat
    [channel.socket:tomcat1]
    port=11009
    host=127.0.0.1
 
    [ajp13:tomcat1]
    channel=channel.socket:tomcat1
 
    # Second Tomcat
    [channel.socket:tomcat2]
    port=12009
    host=127.0.0.1
 
    [ajp13:tomcat2]
    channel=channel.socket:tomcat2
 
    # Load Balance
    [lb:lb1]
    worker=ajp13:tomcat1
    worker=ajp13:tomcat2
 
    # Uri mapping
    [uri:/*.jsp]
    group=lb:lb1

3.2 第一个 Tomcat 的 JK2 配置文件 jk2.properties
# 这个是第一个 Tomcat 的 JK2 配置文件,位于第一个 Tomcat 安装目录下的 conf 目录中
# 找到 channelSocket.port=8009
# 取消注释,并修改为

    channelSocket.port=11009

3.3 第一个 Tomcat 的配置文件 server.xml
# 这个是第一个 Tomcat 的配置文件,位于第一个 Tomcat 安装目录下的 conf 目录中
# 找到

    <Server port="8005" shutdown="SHUTDOWN" debug="0">

# 修改为

    <Server port="11005" shutdown="SHUTDOWN" debug="0">

# 开启 JK2 AJP connector,关闭其它 connector (也就是把其它的 connector 删除或注释掉)
#
修改 JK2 AJP connector 的端口为 11009,修改后的 connector 可能会象下面的样子

    <Connector className="org.apache.ajp.tomcat4.Ajp13Connector"
        port="11009"
        minProcessors="5"
        maxProcessors="75"
        acceptCount="10"
        debug="0"/>

# 为需要集群支持的 webapp context,添加如下manager

    <Valve className="org.apache.catalina.session.ReplicationValve"
        filter=".*\.gif;.*\.jpg;.*\.jpeg;.*\.js"
        debug="0"/>
    <Manager className="org.apache.catalina.session.InMemoryReplicationManager"
        debug="10"
        printToScreen="true"
        saveOnRestart="false"
        maxActiveSessions="-1"
        minIdleSwap="-1"
        maxIdleSwap="-1"
        maxIdleBackup="-1"
        pathname="null"
        printSessionInfo="true"
        checkInterval="10"
        expireSessionsOnShutdown="false"
        serviceclass="org.apache.catalina.cluster.mcast.McastService"
        mcastAddr="228.1.2.3"
        mcastPort="45566"
        mcastFrequency="500"
        mcastDropTime="5000"
        tcpListenAddress="auto"
        tcpListenPort="4001"
        tcpSelectorTimeout="100"
        tcpThreadCount="2"
        useDirtyFlag="true">
        </Manager>

3.4 第一个 Tomcat 的启动脚本 catalina.sh
# 这个是第一个 Tomcat 的 启动脚本,位于第一个 Tomcat 安装目录下的 bin 目录中
# 添加启动环境变量如下

    JAVA_HOME=/usr/java/jdk
      CATALINA_HOME=/www/server/tomcat1

# 此处的 JAVA_HOME 指向系统实际安装 JDK 的路径
#
此处的 CATALINA_HOME 指向第一个 Tomcat 的安装路径

3.5 由第一个 Tomcat 复制得到第二个 Tomcat

    cp -R tomcat1 tomcat2

3.6 第二个 Tomcat 的 JK2 配置文件 jk2.properties
# 参考 3.2
# 修改 channelSocket.port 为

    channelSocket.port=12009

# 注意和第一个 Tomcat 的差别

3.7 第二个 Tomcat 的配置文件 server.xml
# 参考 3.3
# 修改关闭端口为

    <Server port="12005" shutdown="SHUTDOWN" debug="0">

# 修改 JK2 AJP connector 的端口为 12009,修改后的 connector 可能会象下面的样子

    <Connector className="org.apache.ajp.tomcat4.Ajp13Connector"
        port="12009"
        minProcessors="5"
        maxProcessors="75"
        acceptCount="10"
        debug="0"/>

# 注意和第一个 Tomcat 的差别

3.8 第二个 Tomcat 的启动脚本 catalina.sh
# 参考 3.4
# 添加启动环境变量如下

    JAVA_HOME=/usr/java/jdk
      CATALINA_HOME=/www/server/tomcat2

# 此处的 JAVA_HOME 指向系统实际安装 JDK 的路径
#
此处的 CATALINA_HOME 指向第二个 Tomcat 的安装路径
#
注意和第一个 Tomcat 的差别

4. 完成
4.1 重起 Apache

     $apache/bin/apachectl graceful

4.2 启动第一个 Tomcat

     $tomcat1/bin/catalina.sh start

4.3 启动第二个 Tomcat

     $tomcat2/bin/catalina.sh start

5. 参考文献
http://www-900.ibm.com/developerWorks/cn/java/l-jetspeed/
http://www.filip.net/tomcat/
(申明:本文来源于网络,摘录于此,仅为日后方便查看)


Tomcat5.5集群配置

网络上有好多关于 Tomcat 集群配置的文章,但有些是以 Tomcat 4 为基础的,有的并不是讲的很清楚,自己摸索了半天,试验成功了,现把简要过程写出来,让你在几分钟内体验一下 Tomcat Cluster 。

一、配置环境

下载和安装 JRE 1.5 最新版 (1.5.06)
下载和安装 Tomcat 最新版 (5.5.12),假定安装目录为 C:\Program Files\Apache Software Foundation\Tomcat 5.5
二、使 Tomcat 集群配置生效

修改 Tomcat 安装目录\conf\server.xml ,把 Server/Service/Engine/Host 下的 Cluster 结点前后的注释符(<!-- 和 -->)删除,并保存
三、配置第二个 Tomcat 实例

在 C:\Program Files\Apache Software Foundation\ 下新建目录 Tomcat 5.5 Instance1
将 C:\Program Files\Apache Software Foundation\Tomcat 5.5 目录下的全部内容复制到 C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1
修改 新实例的服务器配置文件 (C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1\conf\server.xml),把其中的 Server/Service/Connector 的端口更改,以避免和第一个冲突(8080 -> 9080,8009 -> 9009,8443 -> 9443)
修改 Cluster/Receiver 结点的 tcpListenPort 端口(此端口用于 Session 复制),以避免和第一个冲突(4001 -> 4002)
注:Tomcat Cluster 默认使用多播来建立成员关系,即两个实例的多播的地址和端口一样,就可以互相认为是同一个 Cluster 的成员。

四、启动验证两个 Tomcat 实例能否正常工作

直接用程序菜单里的 Monitor Tomcat 来启动第一个实例(或在服务器里启动)
第二个实例启动稍微麻烦一些,在 C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1\Bin 下建一个 startup.bat ,用如下 java 命令来启动:
"C:\Program Files\Java\j实re1.5.0_06\bin\java.exe" -jar .\bootstrap.jar -Dcatalina.home="C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1" -Dcatalina.base="C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1" -Djava.endorsed.dirs="C:\Program Files\Apache Software Foundation\Tomcat 5.5\common\endorsed" -Djava.io.tmpdir="C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1\temp" -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file="C:\Program Files\Apache Software Foundation\Tomcat 5.5 Instance1\conf\logging.properties" start

看起来挺长,其实主要是第二个实例的安装目录太长的缘故,直接执行此批处理就可以启动第二个实例,如果配置正确,应该可以看到集群管理器启动,并和第一个实例   建立成员关系的信息。

五、写一个简单Web应用,能显示和设置 Session 属性值,以供测试

如果有开发工具,新建一个 Web App ,假设为 TomcatDemo
新增 index.jsp ,加入如下代码:
<%@ page contentType="text/html; charset=UTF-8" import="java.util.*"%>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info: <%out.print(request.getLocalAddr() + " : " + request.getLocalPort());%>
<%
out.println("<br> ID " + session.getId());

// 如果有新的 Session 属性设置
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>");

Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
  String name = (String)e.nextElement();
  String value = session.getAttribute(name).toString();
  out.println( name + " = " + value);
  }
%>
<form action="index.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>


以上代码主要是显示服务器信息和 Session 值,并包含一个 Form ,可以随时新建一个 Session 属性值

修改此用应用的 Web.xml ,加入 distributable 属性,表示 Tomcat 要为此 Web 应用复制 Session  
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2eehttp://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
    <display-name>TomcatDemo</display-name>
    <distributable/>
</web-app>

将应用打包成 WAR 文件,分别上现两个实例的 Tomcat Manager 来部署
(如 果没有 Java 开发工具,可以直接建立一个 TomcatDemo 的目录,用 Notepad 将如上的内容复制并保存成 index.jsp,然后在此目录下新建子目录 WEB-INF,再用 Notepad 新建一 Web.xml 文件,将上面的代码复制保存,然后将此目录压缩成 Zip 文件,再把后缀改成 .war ,或利用 jar 命令来创建 .war 文件)

六、测试 Tomcat 集群和 Session 复制的是否工作

在 IE 中打开第一个实例中的 TomcatDemo (http://localhost:8080/TomcatDemo),在 Form 里随便设置一个 Session 属性,如 MyName = foo
将 IE 地址栏中的地址修改为第二个实例中的 TomcatDemo(http://localhost:9080/TomcatDemo),刷新,就可以看到注意到 SessionID 不变, MyName 的属性值已有了
同样,如果在第二实例中设置的值,在第一个实例的页面中也能看到
注意:必须在同一个 IE 窗口中进行如上测试,以保证是同一个 Session ,如果是两个窗口,则 Session 可能不同,也互相看不到 Session 复制的结果。

七、其它工作

上述只实现了 Session 复制,而没有实现 Load Balance(负载均衡),这可以利用 Apache 等来实现,网上有很多相关文章,可能参考)

(http://www.fanqiang.com)




-------------------
实践中整理出tomcat集群和负载均衡
(一)环境说明
(1)服务器有4台,一台安装apache,三台安装tomcat
(2)apache2.0.55、tomcat5.5.15、jk2.0.4、jdk1.5.6或jdk1.4.2
(3)ip配置,一台安装apache的ip为192.168.0.88,三台安装tomcat的服务器ip分别为192.168.0.1/2/4
(二)安装过程
(1)在三台要安装tomcat的服务器上先安装jdk
(2)配置jdk的安装路径,在环境变量path中加入jdk的bin路径,新建环境变量JAVA_HOME指向jdk的安装路径
(3)在三台要安装tomcat的服务器上分别安装tomcat,调试三个tomcat到能够正常启动
(4)tomcat的默认WEB服务端口是8080,默认的模式是单独服务,我的三个tomcat的WEB服务端口修改为7080/8888/9999
修改位置为tomcat的安装目录下的conf/server.xml
修改前的配置为
    <Connector port="8080" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" redirectPort="8443" acceptCount="100"
               connectionTimeout="20000" disableUploadTimeout="true" />
修改后的配置为
    <Connector port="7080" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" redirectPort="8443" acceptCount="100"
               connectionTimeout="20000" disableUploadTimeout="true" />
依次修改每个tomcat的监听端口(7080/8888/9999)

(5)分别测试每个tomcat的启动是否正常
http://192.168.0.1:7080
http://192.168.0.2:8888
http://192.168.0.4:9999
(三)负载均衡配置过程
(1)在那台要安装apache的服务器上安装apache2.0.55,我的安装路径为默认C:\Program Files\Apache Group\Apache2
(2)安装后测试apache能否正常启动,调试到能够正常启动http://192.168.0.88
(3)下载jk2.0.4后解压缩文件
(4)将解压缩后的目录中的modules目录中的mod_jk2.so文件复制到apache的安装目录下的modules目录中,我的为C:\Program Files\Apache Group\Apache2\modules
(5)修改apache的安装目录中的conf目录的配置文件httpd.conf,在文件中加LoadModule模块配置信息的最后加上一句LoadModule jk2_module modules/mod_jk2.so
(6)分别修改三个tomcat的配置文件conf/server.xml,修改内容如下
修改前
    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host). -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm1">        
    -->
        
    <!-- Define the top level container in our container hierarchy -->
    <Engine name="Catalina" defaultHost="localhost">
修改后
    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host). -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :-->
    <Engine name="Standalone" defaultHost="localhost" jvmRoute="tomcat1">        
    
        
    <!-- Define the top level container in our container hierarchy
    <Engine name="Catalina" defaultHost="localhost">
    -->
将其中的jvmRoute="jvm1"分别修改为jvmRoute="tomcat1"和jvmRoute="tomcat2"和jvmRoute="tomcat3"

(7)然后重启三个tomcat,调试能够正常启动。
(8)在apache的安装目录中的conf目录下创建文件workers2.propertie,写入文件内容如下

# fine the communication channel
[channel.socket:192.168.0.1:8009]
info=Ajp13 forwarding over socket
#配置第一个服务器
tomcatId=tomcat1 #要和tomcat的配置文件server.xml中的jvmRoute="tomcat1"名称一致
debug=0
lb_factor=1 #负载平衡因子,数字越大请求被分配的几率越高

# Define the communication channel
[channel.socket:192.168.0.2:8009]
info=Ajp13 forwarding over socket
tomcatId=tomcat2
debug=0
lb_factor=1

# Define the communication channel
[channel.socket:192.168.0.4:8009]
info=Ajp13 forwarding over socket
tomcatId=tomcat3
debug=0
lb_factor=1

[status:]
info=Status worker, displays runtime information.  

[uri:/jkstatus.jsp]
info=Display status information and checks the config file for changes.
group=status:

[uri:/*]
info=Map the whole webapp
debug=0
(9)在三个tomcat的安装目录中的webapps建立相同的应用,我和应用目录名为TomcatDemo,在三个应用目录中建立相同 WEB-INF目录和页面index.jsp,index.jsp的页面内容如下
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<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.print("<b>Session 列表</b>");

  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="index.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>
(10)重启apache服务器和三个tomcat服务器,到此负载 均衡已配置完成。测试负载均衡先测试apache,访问http://192.168.0.88/jkstatus.jsp
能否正常访问,并查询其中的内容,有三个tomcat的相关配置信息和负载说明,访问http://192.168.0.88/TomcatDemo/index.jsp看能够运行,
能运行,则已建立负载均衡。
(四)tomcat集群配置
(1)负载均衡配置的条件下配置tomcat集群
(2)分别修改三个tomcat的配置文件conf/server.xml,修改内容如下
修改前
        <!--
        <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
                 managerClassName="org.apache.catalina.cluster.session.DeltaManager"
                 expireSessionsOnShutdown="false"
                 useDirtyFlag="true"
                 notifyListenersOnReplication="true">

            <Membership
                className="org.apache.catalina.cluster.mcast.McastService"
                mcastAddr="228.0.0.4"
                mcastPort="45564"
                mcastFrequency="500"
                mcastDropTime="3000"/>

            <Receiver
                className="org.apache.catalina.cluster.tcp.ReplicationListener"
                tcpListenAddress="auto"
                tcpListenPort="4001"
                tcpSelectorTimeout="100"
                tcpThreadCount="6"/>

            <Sender
                className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
                replicationMode="pooled"
                ackTimeout="5000"/>

            <Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
                   filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
                  
            <Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
                      tempDir="/tmp/war-temp/"
                      deployDir="/tmp/war-deploy/"
                      watchDir="/tmp/war-listen/"
                      watchEnabled="false"/>
                      
            <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
        </Cluster>
        -->  
修改后
        <!-- modify by whh -->
        <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
                 managerClassName="org.apache.catalina.cluster.session.DeltaManager"
                 expireSessionsOnShutdown="false"
                 useDirtyFlag="true"
                 notifyListenersOnReplication="true">

            <Membership
                className="org.apache.catalina.cluster.mcast.McastService"
                mcastAddr="228.0.0.4"
                mcastPort="45564"
                mcastFrequency="500"
                mcastDropTime="3000"/>

            <Receiver
                className="org.apache.catalina.cluster.tcp.ReplicationListener"
                tcpListenAddress="auto"
                tcpListenPort="4001"
                tcpSelectorTimeout="100"
                tcpThreadCount="6"/>

            <Sender
                className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
                replicationMode="pooled"
                ackTimeout="5000"/>

            <Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
                   filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
                  
            <Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
                      tempDir="/tmp/war-temp/"
                      deployDir="/tmp/war-deploy/"
                      watchDir="/tmp/war-listen/"
                      watchEnabled="false"/>
                      
            <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
        </Cluster>
       <!-- modify by whh -->      
将集群配置选项的注释放开即可,如上。
(3)重启三个tomcat。到此tomcat的集群已配置完成。  
  
mail:wanghh2000@163.com
王海辉
posted on 2006-11-11 22:00 Franky 阅读(738) 评论(0)  编辑  收藏 所属分类: IT知识

只有注册用户登录后才能发表评论。


网站导航: